Skip to main content
Code running inside a sandbox can fail — especially AI-generated code. This tutorial covers every error-handling pattern you need: checking exit codes, catching typed exceptions, handling timeouts, and streaming stderr for real-time debugging.

What you’ll learn

  1. Check exit codes and stderr from command results
  2. Catch BoxliteError and other exceptions for infrastructure errors
  3. Handle timeouts safely so long-running commands don’t block forever
  4. Stream stderr in real time using the low-level execution API

Prerequisites

Requires Python 3.10+.

Step 1: Check exit codes

Every exec() call returns a result with an exit code, stdout, and stderr. The exec() method does not raise an exception for non-zero exit codes — you need to check them yourself.
exit_codes.py

ExecResult fields

Step 2: Catch infrastructure exceptions

While exec() returns non-zero exit codes without raising, BoxLite does raise exceptions for infrastructure failures — invalid images, command-not-found, config errors, timeouts, and more. The exception hierarchy is:
exceptions.py
Key distinction: exec() returns non-zero exit codes as data (check result.exit_code). It only raises exceptions for infrastructure failures like command-not-found, which means the command couldn’t be started at all.

Step 3: Handle timeouts safely

When a command runs too long, use asyncio.wait_for() (Python) or Promise.race() (Node.js) to set a deadline. The guest process may keep running inside the VM after a timeout, but it will be cleaned up when the box shuts down.
timeout.py

Timeout with a helper function

For repeated use, wrap the pattern in a helper.
timeout_helper.py

Advanced: kill the guest process explicitly

If you need to kill the timed-out process instead of letting it run until the box shuts down, use the low-level execution API.
timeout_kill.py

Step 4: Stream stderr in real time

For long-running commands, you might want to see errors as they happen instead of waiting for the command to finish. Use the low-level execution API with async iterators.
The high-level SimpleBox.exec() collects all output and returns it as a single string. For real-time streaming, use the low-level API via Boxlite.default() and runtime.create().
stream_stderr.py
Each stream (stdout, stderr) can only be iterated once. After iteration, the stream is consumed.

Debugging tips

Enable debug logging

Set the RUST_LOG environment variable to see detailed BoxLite internals — VM lifecycle, image pulls, command execution, and network setup.

Check box status

If commands fail unexpectedly, check whether the box is still running.

Common failure patterns

What’s next?

Execute AI-generated code

Use CodeBox for Python code execution with auto-install and output capture.

Run services with port forwarding

Start servers inside boxes and access them from the host.

Errors & metrics reference (Python)

Full reference for all exception types, error variants, and metrics.

Errors & metrics reference (Node.js)

Node.js SDK error types, metrics API, and monitoring patterns.