Error Handling
All errors thrown by Theatrical extend TheatricalError, which extends the native Error class. This means you can catch them with a standard try/catch and narrow to specific types with instanceof.
Error hierarchy
TheatricalError├── AuthenticationError — 401 / invalid token├── NotFoundError — 404 / resource doesn't exist│ └── .resourceId — the ID that failed to resolve├── ValidationError — 400 / request failed validation│ └── .fields — { fieldName: message } map├── RateLimitError — 429 / request throttled│ └── .retryAfter — seconds to wait before retrying└── ServerError — 5xx / upstream API errorCatching specific errors
import { TheatricalClient, AuthenticationError, NotFoundError, RateLimitError, ValidationError,} from '@theatrical/sdk';
try { const session = await client.sessions.get('ses-unknown');} catch (err) { if (err instanceof NotFoundError) { console.error(`Session not found: ${err.resourceId}`); } else if (err instanceof RateLimitError) { const waitMs = err.retryAfter * 1000; await new Promise(r => setTimeout(r, waitMs)); // retry... } else if (err instanceof ValidationError) { for (const [field, message] of Object.entries(err.fields)) { console.error(`${field}: ${message}`); } } else { throw err; // re-throw unexpected errors }}Automatic retry
The SDK automatically retries 5xx server errors and 429 rate limit responses using exponential backoff with full jitter. The retry budget is configured on the client:
const client = TheatricalClient.create({ apiKey: process.env.THEATRICAL_API_KEY!, maxRetries: 3, // default});Set maxRetries: 0 to disable automatic retry entirely.