# Error handling
URL: /docs/core/concepts/error-handling

Strict vs non-strict exec, CommandError, SandboxError, and ExecConnectionError.



## Strict mode (default) [#strict-mode-default]

By default, `sb.exec()` throws `CommandError` if the command exits with a non-zero code. This is "strict mode" — it mirrors how shell `set -e` works:

```ts
import { CommandError } from "@alineo-labs/sandbox";

const sb = await client.sandbox({
  image: "debian:bookworm-slim",
  resources: { cpu: "500m", memory: "256Mi" },
});
try {
  await sb.exec("echo 'about to fail'").pipe(process.stdout);
  await sb.exec("exit 42"); // throws CommandError
  await sb.exec("echo 'this never runs'");
} catch (e) {
  if (e instanceof CommandError) {
    console.error(`CommandError: exit ${e.exitCode} — "${e.command}"`);
    // CommandError: exit 42 — "exit 42"
  }
} finally {
  await sb.close();
}
```

`CommandError` properties:

* `exitCode: number` — the process exit code
* `command: string` — the command string
* `sandboxId: string` — which sandbox it ran in

## Non-strict mode [#non-strict-mode]

Pass `{ strict: false }` to get the exit code in the result instead of throwing:

```ts
const { exitCode } = await sb.exec("test -f /etc/hosts", { strict: false });
if (exitCode === 0) {
  console.log("file exists");
} else {
  console.log("file missing");
}
```

This is useful for commands where a non-zero exit is a valid outcome (like `test`, `grep`, `diff`).

## Checking exit code and branching [#checking-exit-code-and-branching]

Combine non-strict exec with conditional logic:

```ts
const sb = await client.sandbox({
  image: "debian:bookworm-slim",
  resources: { cpu: "500m", memory: "256Mi" },
});
try {
  const { exitCode } = await sb.exec("exit 1", { strict: false });
  if (exitCode === 0) {
    await sb.exec("echo success").pipe(process.stdout);
  } else {
    await sb.exec("echo 'command failed, handled gracefully'").pipe(process.stdout);
  }
} finally {
  await sb.close();
}
```

Or use `when` from `@alineo-labs/workflow` for the same pattern in a builder:

```ts
sb.exec("exit 1", { strict: false });
sb.when(
  (ctx) => ctx.exitCode === 0,
  (sb) => sb.exec("echo success"),
  (sb) => sb.exec("echo failure"),
);
```

## Other error types [#other-error-types]

### SandboxError [#sandboxerror]

Thrown when a sandbox fails to create, boot, or reach `Running` state:

```ts
import { SandboxError } from "@alineo-labs/sandbox";

try {
  const sb = await client.sandbox({
    image: "nonexistent:latest",
    resources: { cpu: "500m", memory: "256Mi" },
  });
} catch (e) {
  if (e instanceof SandboxError) {
    console.error(`SandboxError: ${e.message}`, e.sandboxId ?? "");
  }
}
```

`SandboxError.sandboxId` may be set if the container was assigned an ID before failing.

### ExecConnectionError [#execconnectionerror]

Thrown when execd inside the sandbox never becomes ready. The container is running from OpenSandbox's perspective, but the exec daemon isn't accepting connections after the retry window:

```ts
import { ExecConnectionError } from "@alineo-labs/sandbox";

try {
  await sb.exec("echo test");
} catch (e) {
  if (e instanceof ExecConnectionError) {
    console.error(`ExecConnectionError: ${e.message}`);
    // execd not ready for sandbox <id>
  }
}
```

## Error hierarchy [#error-hierarchy]

```
Error
└── WorkflowError
    ├── SandboxError       — container failed to start or reach Running
    ├── ExecConnectionError — execd not ready after retry window
    └── CommandError        — non-zero exit code (strict mode)
```

Import from `@alineo-labs/sandbox`:

```ts
import {
  CommandError,
  SandboxError,
  ExecConnectionError,
  WorkflowError,
} from "@alineo-labs/sandbox";
```

## Catching all alineo errors [#catching-all-alineo-errors]

Use `WorkflowError` as the base class to catch any alineo-specific error:

```ts
import { WorkflowError } from "@alineo-labs/sandbox";

try {
  await sb.exec("cmd");
} catch (e) {
  if (e instanceof WorkflowError) {
    console.error("alineo error:", e.message);
  } else {
    throw e; // re-throw unexpected errors
  }
}
```
