Error Handling
The SDK provides typed errors for comprehensive error handling.
Error Types
All SDK errors extend the base DeIterateError class:
typescript
import {
DeIterateError,
ValidationError,
AuthenticationError,
AuthorizationError,
NotFoundError,
RateLimitError,
ConflictError,
InternalError,
} from '@deiterate/sdk';Error Hierarchy
DeIterateError (base)
├── ValidationError (400)
├── AuthenticationError (401)
├── AuthorizationError (403)
├── NotFoundError (404)
├── ConflictError (409)
├── RateLimitError (429)
└── InternalError (500)Handling Specific Errors
ValidationError
Thrown when request data is invalid:
typescript
try {
await client.risks.create({
name: '', // Invalid: empty name
});
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation failed:', error.message);
console.error('Field errors:', error.errors);
// { name: ['Name is required'] }
}
}AuthenticationError
Thrown when authentication fails:
typescript
try {
await client.risks.list();
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Authentication failed:', error.message);
// "Invalid or expired API token"
// Refresh token or re-authenticate
}
}AuthorizationError
Thrown when the user lacks permissions:
typescript
try {
await client.users.delete('user-123');
} catch (error) {
if (error instanceof AuthorizationError) {
console.error('Not authorized:', error.message);
// "Insufficient permissions for this action"
}
}NotFoundError
Thrown when a resource doesn't exist:
typescript
try {
const risk = await client.risks.get('non-existent-id');
} catch (error) {
if (error instanceof NotFoundError) {
console.error('Resource not found:', error.message);
console.error('Resource type:', error.resourceType);
console.error('Resource ID:', error.resourceId);
}
}RateLimitError
Thrown when rate limits are exceeded:
typescript
try {
// Many rapid requests...
for (let i = 0; i < 1000; i++) {
await client.risks.list();
}
} catch (error) {
if (error instanceof RateLimitError) {
console.error('Rate limited');
console.error('Retry after:', error.retryAfter, 'seconds');
// Wait and retry
await sleep(error.retryAfter * 1000);
}
}ConflictError
Thrown when there's a resource conflict:
typescript
try {
await client.users.create({
email: 'existing@example.com', // Already exists
});
} catch (error) {
if (error instanceof ConflictError) {
console.error('Conflict:', error.message);
// "A user with this email already exists"
}
}InternalError
Thrown for server-side errors:
typescript
try {
await client.risks.list();
} catch (error) {
if (error instanceof InternalError) {
console.error('Server error:', error.message);
console.error('Request ID:', error.requestId);
// Log for support and retry later
}
}Comprehensive Error Handler
Handle all error types in one place:
typescript
import {
DeIterateError,
ValidationError,
AuthenticationError,
AuthorizationError,
NotFoundError,
RateLimitError,
ConflictError,
InternalError,
} from '@deiterate/sdk';
async function safeRequest<T>(fn: () => Promise<T>): Promise<T | null> {
try {
return await fn();
} catch (error) {
if (error instanceof ValidationError) {
console.error('❌ Validation error:', error.message);
return null;
}
if (error instanceof AuthenticationError) {
console.error('🔐 Authentication required');
// Trigger re-authentication flow
return null;
}
if (error instanceof AuthorizationError) {
console.error('🚫 Permission denied:', error.message);
return null;
}
if (error instanceof NotFoundError) {
console.error('🔍 Not found:', error.resourceId);
return null;
}
if (error instanceof RateLimitError) {
console.error(`⏳ Rate limited. Retry in ${error.retryAfter}s`);
await sleep(error.retryAfter * 1000);
return safeRequest(fn); // Retry
}
if (error instanceof ConflictError) {
console.error('⚠️ Conflict:', error.message);
return null;
}
if (error instanceof InternalError) {
console.error('💥 Server error. Request ID:', error.requestId);
return null;
}
// Unknown error
console.error('❓ Unknown error:', error);
throw error;
}
}
// Usage
const risks = await safeRequest(() => client.risks.list());Error Properties
All errors include useful properties:
typescript
interface DeIterateError {
message: string; // Human-readable error message
status: number; // HTTP status code
code: string; // Error code (e.g., 'VALIDATION_ERROR')
requestId?: string; // Request ID for support
}Retry Strategies
Exponential Backoff
typescript
async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3
): Promise<T> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (error instanceof RateLimitError) {
const delay = error.retryAfter * 1000;
await sleep(delay);
continue;
}
if (error instanceof InternalError && attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
await sleep(delay);
continue;
}
throw error;
}
}
throw new Error('Max retries exceeded');
}Next Steps
- Pagination - Handle large result sets
- API Reference - Explore all methods