Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions packages/js-sdk/src/envd/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ export function handleRpcError(err: unknown): Error {
return formatSandboxTimeoutError(err.message)
case Code.Canceled:
return new TimeoutError(
`${err.message}: This error is likely due to exceeding 'requestTimeoutMs'. You can pass the request timeout value as an option when making the request.`
`${err.message}: This error is likely due to exceeding 'requestTimeoutMs'. You can pass the request timeout value as an option when making the request.`,
undefined,
'request_timeout'
)
case Code.DeadlineExceeded:
return new TimeoutError(
`${err.message}: This error is likely due to exceeding 'timeoutMs' — the total time a long running request (like command execution or directory watch) can be active. It can be modified by passing 'timeoutMs' when making the request. Use '0' to disable the timeout.`
`${err.message}: This error is likely due to exceeding 'timeoutMs' — the total time a long running request (like command execution or directory watch) can be active. It can be modified by passing 'timeoutMs' when making the request. Use '0' to disable the timeout.`,
undefined,
'execution_timeout'
)
default:
return new SandboxError(`${err.code}: ${err.message}`)
Expand Down
36 changes: 34 additions & 2 deletions packages/js-sdk/src/errors.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
/**
* The type of timeout that occurred.
*
* - `"sandbox_timeout"` – the sandbox itself timed out (idle / max lifetime).
* - `"request_timeout"` – a single HTTP / RPC request exceeded its deadline.
* - `"execution_timeout"` – a long-running operation (process, watch, etc.) exceeded its allowed duration.
*/
export type TimeoutType =
| 'sandbox_timeout'
| 'request_timeout'
| 'execution_timeout'

// This is the message for the sandbox timeout error when the response code is 502/Unavailable
export function formatSandboxTimeoutError(message: string) {
return new TimeoutError(
`${message}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeoutMs' when starting the sandbox or calling '.setTimeout' on the sandbox with the desired timeout.`
`${message}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeoutMs' when starting the sandbox or calling '.setTimeout' on the sandbox with the desired timeout.`,
undefined,
'sandbox_timeout'
)
}

Expand Down Expand Up @@ -30,11 +44,29 @@ export class SandboxError extends Error {
* The [deadline_exceeded] error type is caused by exceeding the timeout for command execution, watch, etc.
*
* The [unknown] error type is sometimes caused by the sandbox timeout when the request is not processed correctly.
*
* Use the {@link timeoutType} property to determine which kind of timeout occurred
* without having to parse the error message.
*/
export class TimeoutError extends SandboxError {
constructor(message: string, stackTrace?: string) {
/**
* Indicates which kind of timeout occurred.
*
* - `"sandbox_timeout"` – the sandbox itself timed out (idle / max lifetime).
* - `"request_timeout"` – a single HTTP / RPC request exceeded its deadline.
* - `"execution_timeout"` – a long-running operation (process, watch, etc.) exceeded its allowed duration.
* - `undefined` – the timeout type could not be determined.
*/
readonly timeoutType?: TimeoutType

constructor(
message: string,
stackTrace?: string,
timeoutType?: TimeoutType
) {
super(message, stackTrace)
this.name = 'TimeoutError'
this.timeoutType = timeoutType
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/js-sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export {
BuildError,
FileUploadError,
} from './errors'
export type { TimeoutType } from './errors'
export type { Logger } from './logs'

export { getSignature } from './sandbox/signature'
Expand Down
8 changes: 5 additions & 3 deletions packages/python-sdk/e2b/envd/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ def handle_rpc_exception(e: Exception):
)
elif e.status == Code.canceled:
return TimeoutException(
f"{e.message}: This error is likely due to exceeding 'request_timeout'. You can pass the request timeout value as an option when making the request."
f"{e.message}: This error is likely due to exceeding 'request_timeout'. You can pass the request timeout value as an option when making the request.",
timeout_type="request_timeout",
)
elif e.status == Code.deadline_exceeded:
return TimeoutException(
f"{e.message}: This error is likely due to exceeding 'timeout' — the total time a long running request (like process or directory watch) can be active. It can be modified by passing 'timeout' when making the request. Use '0' to disable the timeout."
f"{e.message}: This error is likely due to exceeding 'timeout' — the total time a long running request (like process or directory watch) can be active. It can be modified by passing 'timeout' when making the request. Use '0' to disable the timeout.",
timeout_type="execution_timeout",
)
else:
return SandboxException(f"{e.status}: {e.message}")
Expand All @@ -58,4 +60,4 @@ def authentication_header(

encoded = base64.b64encode(value.encode("utf-8")).decode("utf-8")

return {"Authorization": f"Basic {encoded}"}
return {"Authorization": f"Basic {encoded}"}
17 changes: 14 additions & 3 deletions packages/python-sdk/e2b/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
def format_sandbox_timeout_exception(message: str):
return TimeoutException(
f"{message}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeout' when starting the sandbox or calling '.set_timeout' on the sandbox with the desired timeout."
f"{message}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeout' when starting the sandbox or calling '.set_timeout' on the sandbox with the desired timeout.",
timeout_type="sandbox_timeout",
)


def format_request_timeout_error() -> Exception:
return TimeoutException(
"Request timed out — the 'request_timeout' option can be used to increase this timeout",
timeout_type="request_timeout",
)


def format_execution_timeout_error() -> Exception:
return TimeoutException(
"Execution timed out — the 'timeout' option can be used to increase this timeout",
timeout_type="execution_timeout",
)


Expand All @@ -34,9 +37,17 @@ class TimeoutException(SandboxException):
The `canceled` exception type is caused by exceeding request timeout.\n
The `deadline_exceeded` exception type is caused by exceeding the timeout for process, watch, etc.\n
The `unknown` exception type is sometimes caused by the sandbox timeout when the request is not processed correctly.\n

The ``timeout_type`` attribute indicates which kind of timeout occurred:

- ``"sandbox_timeout"`` – the sandbox itself timed out (idle / max lifetime).
- ``"request_timeout"`` – a single HTTP / RPC request exceeded its deadline.
- ``"execution_timeout"`` – a long-running operation (process, watch, …) exceeded its allowed duration.
"""

pass
def __init__(self, message: str = "", timeout_type: str | None = None):
super().__init__(message)
self.timeout_type = timeout_type


class InvalidArgumentException(SandboxException):
Expand Down Expand Up @@ -108,4 +119,4 @@ class BuildException(Exception):
class FileUploadException(BuildException):
"""
Raised when the file upload fails.
"""
"""