Skip to main content

Introduction

The Sandbox package supports two complementary ways to work with command output. You can consume output incrementally through a streaming callback as the command runs, and you can inspect the complete result after execution finishes through the ExecResult value object. Both mechanisms work with every driver.

Streaming Output

The Streaming Callback

The execute() method accepts an optional third argument: a callable that receives output chunks in real time as the command produces them. This is useful for progress reporting, logging, or forwarding output to a user interface.
The callback receives two arguments: Chunks are delivered as they arrive from the process. They are not line-buffered — a chunk may contain a partial line, multiple lines, or even binary data depending on how the underlying process writes to its output streams.

Streaming and Output Caps

The streaming callback receives all output, even when the retained buffer in ExecResult has been truncated due to output caps. This means you can use the callback to write output to a file or database without worrying about the cap:

Streaming with Standard Input

You can combine stdin and the streaming callback in the same call:

Idle Timeout Interaction

The streaming callback does not affect idle timeout tracking. The idle timeout is reset whenever the process produces any output on either stdout or stderr, regardless of whether a callback is provided. However, the callback gives you visibility into when output arrives, which is valuable for diagnosing timeout issues:

The ExecResult API

Every call to execute() returns an ExecResult instance — a readonly value object containing the complete outcome of the execution.

Output Access

The combinedOutput() method appends stderr to stdout, separated by a newline if both are non-empty. This is convenient when you do not need to distinguish between the two streams.

Exit Status

The success() method checks both the exit code and the timeout flag. A command that exits with code 0 but was forcefully terminated due to a timeout is not considered successful. Common exit codes:

Timing

The duration measures the wall-clock time from process start to completion (or termination). It is always available, even for timed-out executions.

Timeout Detection

When a timeout occurs, the exit code is set to 124 and timedOut() returns true. The output captured up to the point of termination is still available through stdout() and stderr().

Truncation Detection

When truncation occurs, only the most recent bytes (up to the cap size) are retained. Earlier output is discarded. This tail-preserving strategy ensures you always have the most recent output, which typically contains error messages and final status information.

Serialization

The toArray() method returns a flat associative array suitable for JSON serialization, logging, or passing to the FakeSandbox for test fixtures.

Common Patterns

Guard Against Failure

The most common pattern is to check success() before using the output:

Capture Output with Timeout Awareness

When running potentially long commands, check for both failure and timeout:

Real-Time Progress with Final Summary

Combine the streaming callback for live updates with the result for a final summary:

Parsing Structured Output

When the command produces JSON or other structured output:

Handling Truncated Output

When working with commands that may produce large output, check for truncation: