diff --git a/sandbox/sdk/python/errors.mdx b/sandbox/sdk/python/errors.mdx index 0ca4188..041b4b6 100644 --- a/sandbox/sdk/python/errors.mdx +++ b/sandbox/sdk/python/errors.mdx @@ -11,6 +11,7 @@ from porter_sandbox import ( NotFoundError, RateLimitError, SandboxError, + SandboxTimeoutError, ServerError, ) ``` @@ -24,6 +25,7 @@ from porter_sandbox import ( | `NotFoundError` | A sandbox, volume, or other resource cannot be found. | | `RateLimitError` | The API returns a rate limit response. | | `ServerError` | The API returns a server-side error. | +| `SandboxTimeoutError` | A request exceeds its timeout. Never retried, since the server may still be executing the request. | Each `SandboxError` includes: diff --git a/sandbox/sdk/python/reference.mdx b/sandbox/sdk/python/reference.mdx index 5e522ef..4d306ec 100644 --- a/sandbox/sdk/python/reference.mdx +++ b/sandbox/sdk/python/reference.mdx @@ -102,10 +102,25 @@ sandbox.terminate() | Method | Description | | ------ | ----------- | | `refresh()` | Refetches status and updates `phase` and `tags`. | -| `exec(command)` | Runs a command in the sandbox and returns stdout, stderr, and exit code. | +| `exec(command, timeout=None)` | Runs a command in the sandbox and returns stdout, stderr, and exit code. | | `logs(since=None, limit=None)` | Fetches structured log lines. | | `terminate()` | Terminates the sandbox. | +### `exec` timeouts + +`exec` is long-running: the client sends no timeout by default, so the call waits for the command to exit. Pass `timeout` (seconds) to cap how long the client waits. When the timeout elapses, the SDK raises `SandboxTimeoutError` and does not retry, since the command may still be running server-side. + +```python +from porter_sandbox import SandboxTimeoutError + +try: + result = sandbox.exec(["sleep", "120"], timeout=30.0) +except SandboxTimeoutError: + print("exec exceeded 30s; the command may still be running in the sandbox") +``` + +The client-wide `timeout` on `Porter` still applies to every other request (30 seconds by default). + ## Volumes Volumes are persistent storage that can be mounted into sandboxes. diff --git a/sandbox/sdk/typescript/errors.mdx b/sandbox/sdk/typescript/errors.mdx index 4565c7e..e234489 100644 --- a/sandbox/sdk/typescript/errors.mdx +++ b/sandbox/sdk/typescript/errors.mdx @@ -11,6 +11,7 @@ import { NotFoundError, RateLimitError, SandboxError, + SandboxTimeoutError, ServerError, } from "porter-sandbox"; ``` @@ -24,6 +25,7 @@ import { | `NotFoundError` | A sandbox, volume, or other resource cannot be found. | | `RateLimitError` | The API returns a rate limit response. | | `ServerError` | The API returns a server-side error. | +| `SandboxTimeoutError` | A request exceeds its timeout. Never retried, since the server may still be executing the request. | Each `SandboxError` includes: diff --git a/sandbox/sdk/typescript/reference.mdx b/sandbox/sdk/typescript/reference.mdx index e51fecb..35906c7 100644 --- a/sandbox/sdk/typescript/reference.mdx +++ b/sandbox/sdk/typescript/reference.mdx @@ -109,10 +109,30 @@ await sandbox.terminate(); | Method | Description | | ------ | ----------- | | `refresh()` | Refetches status and updates `phase` and `tags`. | -| `exec(command)` | Runs a command in the sandbox and returns stdout, stderr, and exit code. | +| `exec(command, requestOptions?)` | Runs a command in the sandbox and returns stdout, stderr, and exit code. | | `logs(options?)` | Fetches structured log lines. | | `terminate()` | Terminates the sandbox. | +### `exec` timeouts + +`exec` is long-running: the client sends no timeout by default, so the call waits for the command to exit. Pass `requestOptions.timeoutMs` to cap how long the client waits. When the timeout elapses, the SDK throws `SandboxTimeoutError` and does not retry, since the command may still be running server-side. + +```typescript +import { SandboxTimeoutError } from "porter-sandbox"; + +try { + const result = await sandbox.exec(["sleep", "120"], { timeoutMs: 30_000 }); +} catch (error) { + if (error instanceof SandboxTimeoutError) { + console.error("exec exceeded 30s; the command may still be running in the sandbox"); + } else { + throw error; + } +} +``` + +The client-wide `timeoutMs` on `Porter` still applies to every other request (30 seconds by default). + ## Volumes Volumes are persistent storage that can be mounted into sandboxes.