Error handling (JavaScript / TypeScript)¶
All SDK errors subclass SistemoError.
import {
Sandbox,
SistemoError, // base class
APIError, // non-2xx (has .status, .detail, .code)
AuthError, // 401 / 403 forbidden
QuotaExceededError, // 403 quota_exceeded — check this BEFORE AuthError
NotFoundError, // 404
RateLimitError, // 429
ExecStartUnconfirmed, // 503 on POST /execs — command MAY be running
JobTimeout, // wait() gave up; the job is still running
} from "@sistemo/sdk";
Hierarchy¶
Error
└── SistemoError
└── APIError(status, detail, code?)
├── AuthError (401, 403 forbidden)
├── QuotaExceededError (403 quota_exceeded) // NOT a subclass of AuthError
├── NotFoundError (404)
├── RateLimitError (429)
└── ExecStartUnconfirmed (503 on POST /execs)
JobTimeout // wait()/stream() client timeout; job still running
SistemoError is also thrown for client-side issues (missing API key, connection error).
Handling specific cases¶
import {
Sandbox,
AuthError,
QuotaExceededError,
RateLimitError,
APIError,
} from "@sistemo/sdk";
try {
const sb = await Sandbox.create();
try {
console.log((await sb.run("uname -a")).stdout);
} finally {
await sb.close();
}
} catch (e) {
if (e instanceof QuotaExceededError) {
console.error("quota:", e.detail); // retry works once you free a machine
} else if (e instanceof AuthError) {
console.error("Check SISTEMO_API_KEY — missing, revoked, or read-only.");
} else if (e instanceof RateLimitError) {
console.error("Rate limited — back off and retry.");
} else if (e instanceof APIError) {
console.error(`API error ${e.status}: ${e.detail} (${e.code})`);
} else {
throw e;
}
}
Fields on APIError¶
| Field | Type | Example |
|---|---|---|
status | number | 403 |
detail | string | "Machine quota exceeded (limit 1)." |
code | string \| undefined | "quota_exceeded" |
See API errors for all code values.