Error Handling
Every SDK rejects with typed errors so you can branch on failure mode instead of parsing strings. The client SDK has the richest hierarchy; the server and MCP packages each have a focused error type.
Client SDK errors
Section titled “Client SDK errors”All client errors extend DivinciError, which carries the machine-readable
code, the HTTP status, an optional details object, and the requestId for
support.
| Error | Status | Thrown when |
|---|---|---|
AuthenticationError | 401 | Invalid, missing, or expired credentials |
ValidationError | 400 | Invalid request parameters (see fieldErrors) |
RateLimitError | 429 | Too many requests (see retryAfter, limit, remaining) |
QuotaExceededError | 429 | Usage quota for the workspace/release is exhausted |
PaymentRequiredError | 402 | An x402-priced resource needs payment |
NotFoundError | 404 | The release, thread, or resource doesn’t exist |
NetworkError | — | Connection failed (see retryable) |
TimeoutError | — | The request exceeded timeout |
StreamError | — | A streaming response failed mid-flight |
import { DivinciClient, RateLimitError, QuotaExceededError, AuthenticationError, PaymentRequiredError,} from "@divinci-ai/client";
try { await client.chat.send(thread.id, "Hello!", { assistantName: "your-assistant-id" });} catch (error) { if (error instanceof RateLimitError) { // Back off using the server-provided hint await sleep((error.retryAfter ?? 1) * 1000); return retry(); }
if (error instanceof QuotaExceededError) { showUpgradePrompt(); return; }
if (error instanceof AuthenticationError) { redirectToLogin(); return; }
if (error instanceof PaymentRequiredError) { // amount + payment URL are available on the error openCheckout(error.getPaymentUrl(), error.getAmountUsd()); return; }
throw error; // unknown — let it bubble}Inspecting an error
Section titled “Inspecting an error”Every DivinciError serializes cleanly for logging:
import { DivinciError } from "@divinci-ai/client";
try { await client.chat.create();} catch (error) { if (error instanceof DivinciError) { console.error(error.toJSON()); // { code, status, details, requestId, message } }}Server SDK errors
Section titled “Server SDK errors”The server SDK throws ServerApiError for any non-2xx API response. It exposes
the same fields — code, status, details, requestId, plus the raw body.
import { ServerApiError } from "@divinci-ai/server";
try { await divinci.workspaces.get("ws_missing");} catch (error) { if (error instanceof ServerApiError) { if (error.status === 404) { // handle not found } console.error(error.code, error.requestId); }}MCP SDK errors
Section titled “MCP SDK errors”Paid tool calls throw PaymentRequiredError (carrying paymentDetails) when no
valid payment accompanies the request. See MCP x402 Payments for
the autopay and manual-retry patterns.
Retry guidance
Section titled “Retry guidance”NetworkError— retry only iferror.retryableis true.RateLimitError— honorretryAfter; use exponential backoff if absent.TimeoutError— safe to retry idempotent reads; be careful retrying sends.AuthenticationError/ValidationError— never retry blindly; fix the cause.
The SDKs already retry transient failures internally up to maxRetries
(default 3). Tune it per client via the constructor, or pass skipRetry on an
individual request through the underlying HTTP client.