Throw descriptive error when sandbox is killed mid-request#291
Throw descriptive error when sandbox is killed mid-request#291mishushakov wants to merge 6 commits into
Conversation
When the sandbox is killed or times out while a request to the Jupyter server is in flight (runCode/run_code or context management), the SDKs surfaced a raw socket error (e.g. ECONNRESET). Now they detect the closed connection, confirm the sandbox is gone via its health check, and throw a descriptive SandboxError/SandboxException instead. If the sandbox is still running (or its state can't be determined), the original error propagates unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PR SummaryLow Risk Overview JS adds Reviewed by Cursor Bugbot for commit bcaab38. Bugbot is set up for automated code reviews on this repo. Configure here. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Matches the existing 502 mapping in extractError/extract_exception and the base SDK convention: a dead sandbox surfaces as TimeoutError / TimeoutException. When the health probe is inconclusive or the sandbox is still running, the original transport error propagates unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 17cce6a. Configure here.
Consolidate the two-line catch handler into a single formatRequestError call that returns the error to throw, matching the main SDK pattern (e2b-dev/E2B#1419). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Align with e2b-dev/E2B#1419, which names the health-check-aware error wrappers handle*Error / handle_*_exception: - JS: formatRequestError -> handleRequestError - Python: _raise_if_sandbox_killed -> _handle_connection_error Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The kill-during-execution tests used time.sleep(60), which in JS matched the default execution timeout (DEFAULT_TIMEOUT_MS = 60s). A slow kill could let the body-timer abort (or the sleep completing) end the request instead of the connection reset, masking the sandbox-killed path the test asserts. Bump the sleep to 300s and set an explicit execution timeout well beyond the kill + disconnect-detection window so the sandbox kill is the only thing that ends the request, matching the interrupt test's convention. Add a 60s vitest timeout to the JS test for the disconnect-detection window. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

When the sandbox is killed or times out while a request is in flight,
runCode/run_codeand the context-management methods surfaced a raw socket error (e.g.ECONNRESETon Bun,TypeError: fetch failedon Node,httpx.ReadError/RemoteProtocolErrorin Python). Both SDKs now detect the closed connection across runtimes, confirm via the sandbox health check that it's actually gone, and throw a descriptiveSandboxError/SandboxExceptionsuggestingtimeoutMs/.setTimeoutinstead. If the sandbox is still running or its state can't be determined, the original error propagates unchanged so genuine network issues aren't masked. Includes kill-during-execution tests for JS, Python sync, and Python async (verified against the live API on Node and Bun), plus a patch changeset for both packages.🤖 Generated with Claude Code