Error Handling
The SDK provides two error classes that extend the built-in Error class. All API errors and timeout conditions are surfaced through these types, making error handling predictable with instanceof checks.
import { ChaosError, ChaosTimeoutError } from '@chaoslabs/ai-sdk';ChaosError
The base error class for all SDK errors. Extends the native Error class with optional HTTP metadata.
export class ChaosError extends Error {
constructor(
message: string,
public readonly status?: number,
public readonly code?: string,
public readonly type?: string
) {
super(message);
this.name = 'ChaosError';
}
}Properties
| Property | Type | Description |
|---|---|---|
message | string | Human-readable error description (inherited from Error) |
name | string | Always 'ChaosError' |
status | number | undefined | HTTP status code (e.g., 401, 429, 500) |
code | string | undefined | Machine-readable error code from the API |
type | string | undefined | Error type classification from the API |
ChaosError is thrown for:
- HTTP errors (4xx, 5xx status codes)
- Connection errors
- Stream errors (unexpected close, read failures)
- Aborted requests
ChaosTimeoutError
Thrown when a request exceeds the configured timeout. Extends ChaosError.
export class ChaosTimeoutError extends ChaosError {
constructor(timeoutMs: number) {
super(`Request timed out after ${timeoutMs}ms`);
this.name = 'ChaosTimeoutError';
}
}The timeout is configured via the timeout option when initializing the client (default: 120000ms / 2 minutes). The timer resets on each data chunk received during streaming, so the timeout applies to periods of inactivity rather than total request duration.
Error Handling Patterns
Basic try/catch
import { Chaos, ChaosError, ChaosTimeoutError, WALLET_MODEL } from '@chaoslabs/ai-sdk';
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
try {
const response = await chaos.chat.responses.create({
model: WALLET_MODEL,
input: [{ type: 'message', role: 'user', content: 'Swap 1 ETH to USDC' }],
metadata: {
user_id: 'user-123',
session_id: 'session-456',
wallets: [{ address: '0x...', chain: 'ethereum' }],
},
});
console.log('Success:', response.status);
} catch (error) {
if (error instanceof ChaosTimeoutError) {
console.error('Request timed out — consider increasing the timeout');
} else if (error instanceof ChaosError) {
console.error(`API error: ${error.message}`);
if (error.status === 401) {
console.error('Invalid API key');
} else if (error.status === 429) {
console.error('Rate limited — retry after backoff');
}
} else {
throw error; // Re-throw unexpected errors
}
}Checking Error Order
Since ChaosTimeoutError extends ChaosError, always check for the more specific type first.
try {
await chaos.chat.responses.create(params);
} catch (error) {
// Check ChaosTimeoutError BEFORE ChaosError
if (error instanceof ChaosTimeoutError) {
// Timeout-specific handling
} else if (error instanceof ChaosError) {
// General API error handling
}
}Retry Pattern
import { Chaos, ChaosError, ChaosTimeoutError, WALLET_MODEL } from '@chaoslabs/ai-sdk';
import type { ChatCreateRequestParams } from '@chaoslabs/ai-sdk';
async function withRetry(
chaos: Chaos,
params: ChatCreateRequestParams,
maxRetries = 3
) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await chaos.chat.responses.create(params);
} catch (error) {
if (error instanceof ChaosTimeoutError && attempt < maxRetries) {
console.log(`Attempt ${attempt} timed out, retrying...`);
continue;
}
if (
error instanceof ChaosError &&
error.status === 429 &&
attempt < maxRetries
) {
const delay = Math.pow(2, attempt) * 1000;
console.log(`Rate limited, retrying in ${delay}ms...`);
await new Promise((r) => setTimeout(r, delay));
continue;
}
throw error;
}
}
throw new ChaosError('Max retries exceeded');
}Helper Functions
The SDK also provides helper functions on ChatCreateResponse for common safety checks.
hasRisks
Returns true if any transaction action block has a risk level above 'low'.
export function hasRisks(response: ChatCreateResponse): boolean;
// Usage
if (hasRisks(response)) {
console.log('This response contains elevated risk levels');
}hasBlockers
Returns true if any transaction action block has 'high' or 'critical' risk level, or contains any blocker items.
export function hasBlockers(response: ChatCreateResponse): boolean;
// Usage
if (hasBlockers(response)) {
console.log('Transaction blocked — do not proceed');
}