Skip to content

Error Handling

All errors thrown by the SDK extend a single base type, so you can catch any SDK error in one place or branch on the specific subclass when you need to react differently. The hierarchy is identical across the TypeScript and Python SDKs.

Error hierarchy

Error
└── ImbraceError (base — catch-all for SDK errors)
├── AuthError (401, 403 — invalid or expired credentials)
├── ApiError (4xx/5xx — request rejected by the server)
└── NetworkError (timeout, connection refused, DNS failure)

For specific error messages and known fixes, see Troubleshooting.


AuthError

Raised when the server returns 401 or 403 — credentials are invalid, expired, or revoked.

import { AuthError } from "@imbrace/sdk";
try {
const me = await client.platform.getMe();
} catch (e) {
if (e instanceof AuthError) {
console.error("Re-authenticate:", e.message);
}
}

ApiError

Raised for all other 4xx and 5xx responses (after retries are exhausted for 429/5xx).

import { ApiError } from "@imbrace/sdk";
try {
await client.contacts.get("nonexistent_id");
} catch (e) {
if (e instanceof ApiError) {
console.error(`HTTP ${e.statusCode}: ${e.message}`);
// e.g. "HTTP 404: Contact not found"
}
}
PropertyTypeDescription
statusCodenumberHTTP status code
messagestringError message from server response

NetworkError

Raised when the request never reaches the server — timeout, DNS failure, or connection reset.

import { NetworkError } from "@imbrace/sdk";
try {
await client.platform.getMe();
} catch (e) {
if (e instanceof NetworkError) {
console.error("Cannot reach baseUrl:", e.message);
// e.g. "Request timed out after 30000ms"
}
}

Catching all SDK errors

Import the base type to handle any SDK-originated error in a single block:

import {
ImbraceClient,
ImbraceError,
AuthError,
ApiError,
NetworkError,
} from "@imbrace/sdk";
try {
await client.platform.getMe();
} catch (e) {
if (e instanceof AuthError) return handleAuthError(e);
if (e instanceof ApiError) return handleApiError(e);
if (e instanceof NetworkError) return handleNetworkError(e);
if (e instanceof ImbraceError) return handleUnknown(e);
throw e; // re-throw non-SDK errors
}

Automatic retry behavior

The HTTP transport in both SDKs retries transient failures with exponential backoff.

ConditionAction
HTTP 429 / 503Retry up to 3 times, any method
HTTP 5xx (other)Retry up to 3 times for GET, HEAD, OPTIONS, PUT, DELETE
Network error / timeoutRetry up to 3 times for GET, HEAD, OPTIONS, PUT, DELETE
HTTP 401 / 403No retry — throw AuthError immediately
HTTP 4xx (other)No retry — throw ApiError immediately

POST and PATCH are not retried on timeouts, network errors or 5xx other than 503: the server may already have run them.

Backoff: on 429/503 the SDK waits for the Retry-After header (seconds or HTTP date) when the server sends one, up to 60 s; a longer Retry-After throws ApiError at once. Otherwise 2^retryCount seconds between attempts (1s → 2s → 4s). Total worst-case: 4 attempts.

Configure (1.7.0+): maxRetries sets the number of retries (0 = a single attempt). fetch replaces the fetch used for every request, e.g. to add your own retry, proxy or tracing layer.

const client = new ImbraceClient({
apiKey: process.env.IMBRACE_API_KEY,
maxRetries: 0, // the SDK makes one attempt; retry in your own layer
fetch: myFetch, // optional
});

Request timeout

Configure the timeout when creating the client (default: 30 s). When the timeout fires, the in-flight request is aborted and a NetworkError is thrown/raised.

const client = new ImbraceClient({ timeout: 15_000 }); // milliseconds

Async error handling (Python)

The async client raises identical exception types:

from imbrace import AsyncImbraceClient, AuthError, ApiError
async with AsyncImbraceClient() as client:
try:
me = await client.platform.get_me()
except AuthError:
print("Re-authenticate")
except ApiError as e:
print(f"[{e.status_code}] {e}")

Best practices

// 1. Always handle AuthError separately — credentials need to be refreshed
// 2. Log ApiError.statusCode — 400 = bad params, 404 = not found, 409 = conflict
// 3. Wrap top-level entry points in try/catch
// 4. Don't retry on AuthError — won't help until credentials are fixed
async function safeGetMe(client: ImbraceClient) {
try {
return await client.platform.getMe();
} catch (e) {
if (e instanceof AuthError) {
await refreshCredentials();
return await client.platform.getMe();
}
throw e;
}
}