Errors API
Complete error handling reference for ai.matey.
Error Hierarchy
Section titled “Error Hierarchy”Error└── AIMateyError (base) ├── BackendError │ ├── RateLimitError │ ├── AuthenticationError │ ├── InvalidRequestError │ ├── TimeoutError │ └── ServiceUnavailableError ├── ValidationError ├── AdapterError ├── MiddlewareError ├── RoutingError └── ConfigurationErrorBase Error
Section titled “Base Error”AIMateyError
Section titled “AIMateyError”Base class for all ai.matey errors.
class AIMateyError extends Error { /** Error name */ name: string;
/** Error message */ message: string;
/** Error code */ code: string;
/** Original error (if wrapped) */ cause?: Error;
/** Additional context */ context?: Record<string, any>;
/** Stack trace */ stack?: string;}Example:
try { await bridge.chat({ ... });} catch (error) { if (error instanceof AIMateyError) { console.log('AI Matey error:', error.code); console.log('Context:', error.context); }}Backend Errors
Section titled “Backend Errors”BackendError
Section titled “BackendError”Base class for backend-related errors.
class BackendError extends AIMateyError { /** Backend adapter name */ backend: string;
/** HTTP status code (if applicable) */ statusCode?: number;
/** Response body */ responseBody?: any;
/** Request that caused the error */ request?: IRChatCompletionRequest;}Example:
try { await bridge.chat({ ... });} catch (error) { if (error instanceof BackendError) { console.log('Backend:', error.backend); console.log('Status:', error.statusCode); console.log('Response:', error.responseBody); }}RateLimitError
Section titled “RateLimitError”Thrown when rate limit is exceeded.
class RateLimitError extends BackendError { code = 'RATE_LIMIT_EXCEEDED';
/** Retry after (seconds) */ retryAfter?: number;
/** Limit details */ limit?: { requests: number; period: string; remaining: number; };}Example:
try { await bridge.chat({ ... });} catch (error) { if (error instanceof RateLimitError) { console.log(`Rate limit exceeded. Retry after ${error.retryAfter}s`); console.log(`Limit: ${error.limit.requests} requests per ${error.limit.period}`);
// Wait and retry await new Promise(resolve => setTimeout(resolve, error.retryAfter * 1000)); await bridge.chat({ ... }); }}AuthenticationError
Section titled “AuthenticationError”Thrown when API key is invalid or missing.
class AuthenticationError extends BackendError { code = 'AUTHENTICATION_FAILED';
/** Authentication type */ authType: 'api_key' | 'bearer_token' | 'oauth';}Example:
try { await bridge.chat({ ... });} catch (error) { if (error instanceof AuthenticationError) { console.error('Invalid API key for:', error.backend); console.error('Auth type:', error.authType);
// Prompt for new API key const newKey = await promptForApiKey(); bridge.setBackend(new AnthropicBackendAdapter({ apiKey: newKey })); }}InvalidRequestError
Section titled “InvalidRequestError”Thrown when request is malformed or invalid.
class InvalidRequestError extends BackendError { code = 'INVALID_REQUEST';
/** Validation errors */ errors?: Array<{ field: string; message: string; code: string; }>;}Example:
try { await bridge.chat({ model: null }); // Invalid} catch (error) { if (error instanceof InvalidRequestError) { console.error('Invalid request:', error.message); error.errors?.forEach(err => { console.error(` ${err.field}: ${err.message}`); }); }}TimeoutError
Section titled “TimeoutError”Thrown when request exceeds timeout.
class TimeoutError extends BackendError { code = 'TIMEOUT';
/** Timeout duration (ms) */ timeout: number;
/** Elapsed time (ms) */ elapsed: number;}Example:
const bridge = new Bridge(frontend, backend, { timeout: 5000 });
try { await bridge.chat({ ... });} catch (error) { if (error instanceof TimeoutError) { console.error(`Request timed out after ${error.timeout}ms`);
// Retry with longer timeout bridge.options.timeout = 10000; await bridge.chat({ ... }); }}ServiceUnavailableError
Section titled “ServiceUnavailableError”Thrown when backend service is down or unavailable.
class ServiceUnavailableError extends BackendError { code = 'SERVICE_UNAVAILABLE';
/** Expected recovery time */ retryAfter?: number;}Example:
try { await bridge.chat({ ... });} catch (error) { if (error instanceof ServiceUnavailableError) { console.error(`${error.backend} is unavailable`);
// Try fallback backend bridge.setBackend(fallbackBackend); await bridge.chat({ ... }); }}Validation Errors
Section titled “Validation Errors”ValidationError
Section titled “ValidationError”Thrown when request or response validation fails.
class ValidationError extends AIMateyError { code = 'VALIDATION_FAILED';
/** Field that failed validation */ field?: string;
/** Validation errors */ errors: Array<{ path: string; message: string; value?: any; }>;
/** Schema that failed */ schema?: any;}Example:
try { await bridge.chat({ model: 'gpt-4', messages: [] // Empty messages - invalid });} catch (error) { if (error instanceof ValidationError) { console.error('Validation failed:'); error.errors.forEach(err => { console.error(` ${err.path}: ${err.message}`); }); }}Adapter Errors
Section titled “Adapter Errors”AdapterError
Section titled “AdapterError”Thrown when adapter encounters an error.
class AdapterError extends AIMateyError { code = 'ADAPTER_ERROR';
/** Adapter name */ adapter: string;
/** Adapter type */ adapterType: 'frontend' | 'backend';}Example:
try { await bridge.chat({ ... });} catch (error) { if (error instanceof AdapterError) { console.error(`${error.adapterType} adapter "${error.adapter}" failed`); }}Middleware Errors
Section titled “Middleware Errors”MiddlewareError
Section titled “MiddlewareError”Thrown when middleware encounters an error.
class MiddlewareError extends AIMateyError { code = 'MIDDLEWARE_ERROR';
/** Middleware name */ middleware: string;
/** Phase where error occurred */ phase: 'onRequest' | 'onResponse' | 'onError' | 'onStreamChunk';}Example:
try { await bridge.chat({ ... });} catch (error) { if (error instanceof MiddlewareError) { console.error(`Middleware "${error.middleware}" failed in ${error.phase}`); }}Routing Errors
Section titled “Routing Errors”RoutingError
Section titled “RoutingError”Thrown when router encounters an error.
class RoutingError extends AIMateyError { code = 'ROUTING_ERROR';
/** Current strategy */ strategy: string;
/** Available backends */ backends: string[];}Example:
try { await router.chat({ ... });} catch (error) { if (error instanceof RoutingError) { console.error(`Routing failed with strategy: ${error.strategy}`); console.error(`Available backends: ${error.backends.join(', ')}`); }}AllBackendsFailedError
Section titled “AllBackendsFailedError”Thrown when all backends fail.
class AllBackendsFailedError extends RoutingError { code = 'ALL_BACKENDS_FAILED';
/** Individual backend failures */ failures: Array<{ backend: string; error: Error; }>;}Example:
try { await router.chat({ ... });} catch (error) { if (error instanceof AllBackendsFailedError) { console.error('All backends failed:'); error.failures.forEach(({ backend, error }) => { console.error(` ${backend}: ${error.message}`); }); }}Configuration Errors
Section titled “Configuration Errors”ConfigurationError
Section titled “ConfigurationError”Thrown when configuration is invalid.
class ConfigurationError extends AIMateyError { code = 'INVALID_CONFIGURATION';
/** Configuration field */ field?: string;
/** Expected value/type */ expected?: string;
/** Actual value */ actual?: any;}Example:
try { const bridge = new Bridge(null, backend); // Invalid} catch (error) { if (error instanceof ConfigurationError) { console.error(`Invalid config: ${error.field}`); console.error(`Expected: ${error.expected}`); console.error(`Got: ${error.actual}`); }}Error Handling Patterns
Section titled “Error Handling Patterns”Try-Catch
Section titled “Try-Catch”Basic error handling:
try { const response = await bridge.chat({ ... });} catch (error) { if (error instanceof RateLimitError) { // Handle rate limit await sleep(error.retryAfter * 1000); } else if (error instanceof AuthenticationError) { // Handle auth error console.error('Invalid API key'); } else { // Handle other errors console.error('Unexpected error:', error); }}Error Handler Middleware
Section titled “Error Handler Middleware”Global error handling:
function createErrorHandlerMiddleware() { return { name: 'error-handler',
async onError(error: Error) { if (error instanceof RateLimitError) { console.log('Rate limit exceeded, waiting...'); await sleep(error.retryAfter * 1000); return; // Retry }
if (error instanceof AuthenticationError) { console.error('Auth failed:', error.backend); // Send alert await sendAlert('Authentication failed'); }
// Re-throw to propagate return error; } };}
bridge.use(createErrorHandlerMiddleware());Bridge Error Events
Section titled “Bridge Error Events”Listen to error events:
bridge.on('error', (error) => { if (error instanceof BackendError) { console.error(`Backend ${error.backend} failed`); console.error(`Status: ${error.statusCode}`);
// Log to monitoring service logToSentry(error); }});Router Failover
Section titled “Router Failover”Automatic failover on errors:
const router = new Router(frontend, { backends: [primaryBackend, fallbackBackend], strategy: 'priority', fallbackOnError: true});
router.on('backend:failed', ({ backend, error }) => { console.error(`❌ ${backend} failed: ${error.message}`);});
router.on('backend:switch', ({ from, to, reason }) => { console.log(`🔄 Switched from ${from} to ${to}: ${reason}`);});
// Automatically uses fallback on errorconst response = await router.chat({ ... });Retry Logic
Section titled “Retry Logic”Retry on specific errors:
import { createRetryMiddleware } from 'ai.matey.middleware';
bridge.use(createRetryMiddleware({ maxAttempts: 3, initialDelay: 1000, shouldRetry: (error, attempt) => { // Retry on rate limits and timeouts if (error instanceof RateLimitError) return true; if (error instanceof TimeoutError) return true;
// Don't retry on auth errors if (error instanceof AuthenticationError) return false;
// Retry up to 2 times for other errors return attempt < 2; }}));Error Logging
Section titled “Error Logging”Comprehensive error logging:
function logError(error: Error) { const logData = { timestamp: new Date().toISOString(), name: error.name, message: error.message, stack: error.stack };
if (error instanceof AIMateyError) { logData.code = error.code; logData.context = error.context; }
if (error instanceof BackendError) { logData.backend = error.backend; logData.statusCode = error.statusCode; }
console.error(JSON.stringify(logData, null, 2));
// Send to logging service sendToLogService(logData);}
try { await bridge.chat({ ... });} catch (error) { logError(error);}Error Codes Reference
Section titled “Error Codes Reference”| Code | Error Class | Description |
|---|---|---|
RATE_LIMIT_EXCEEDED |
RateLimitError | API rate limit exceeded |
AUTHENTICATION_FAILED |
AuthenticationError | Invalid API key or token |
INVALID_REQUEST |
InvalidRequestError | Malformed request |
TIMEOUT |
TimeoutError | Request timeout |
SERVICE_UNAVAILABLE |
ServiceUnavailableError | Backend unavailable |
VALIDATION_FAILED |
ValidationError | Request/response validation failed |
ADAPTER_ERROR |
AdapterError | Adapter failure |
MIDDLEWARE_ERROR |
MiddlewareError | Middleware failure |
ROUTING_ERROR |
RoutingError | Routing failure |
ALL_BACKENDS_FAILED |
AllBackendsFailedError | All backends failed |
INVALID_CONFIGURATION |
ConfigurationError | Invalid configuration |
Best Practices
Section titled “Best Practices”1. Always Handle Errors
Section titled “1. Always Handle Errors”// ✅ Goodtry { const response = await bridge.chat({ ... });} catch (error) { console.error('Error:', error);}
// ❌ Badconst response = await bridge.chat({ ... }); // Unhandled errors2. Use Specific Error Types
Section titled “2. Use Specific Error Types”// ✅ Goodcatch (error) { if (error instanceof RateLimitError) { // Handle rate limit specifically } else if (error instanceof AuthenticationError) { // Handle auth error specifically }}
// ❌ Badcatch (error) { console.log('Something went wrong'); // Too generic}3. Log Error Context
Section titled “3. Log Error Context”// ✅ Goodcatch (error) { if (error instanceof BackendError) { console.log('Backend:', error.backend); console.log('Status:', error.statusCode); console.log('Request:', error.request); }}
// ❌ Badcatch (error) { console.log(error.message); // Missing context}4. Implement Graceful Degradation
Section titled “4. Implement Graceful Degradation”// ✅ Goodtry { return await primaryService.chat({ ... });} catch (error) { if (error instanceof ServiceUnavailableError) { return await fallbackService.chat({ ... }); } throw error;}
// ❌ Badtry { return await primaryService.chat({ ... });} catch (error) { throw error; // No fallback}See Also
Section titled “See Also”- Bridge API - Bridge error handling
- Router API - Router error handling
- Middleware API - Middleware error handling
- Testing Guide - Testing error scenarios