- Spec files
npm-anthropic-ai--sdk
Describes: pkg:npm/@anthropic-ai/sdk@0.61.x
- Description
- The official TypeScript library for the Anthropic API providing comprehensive client functionality for Claude AI models.
- Author
- tessl
- Last updated
error-handling.md docs/
1# Error Handling23The Anthropic SDK provides a comprehensive error hierarchy for handling different types of API failures, network issues, and client-side problems. All errors extend the base `AnthropicError` class and include detailed information for debugging and recovery.45## Capabilities67### Error Hierarchy89Comprehensive error types covering all aspects of API interaction and client behavior.1011```typescript { .api }12/**13* Base error class for all Anthropic SDK errors14*/15class AnthropicError extends Error {16/** Error name */17name: string;18/** Error message */19message: string;20/** Error cause (if available) */21cause?: unknown;22}2324/**25* Base class for API-related errors26*/27class APIError extends AnthropicError {28/** HTTP status code */29status: number;30/** Response headers */31headers: Headers;32/** Error details from API response */33error?: APIErrorObject;34/** Request that caused the error */35request?: Request;36}3738interface APIErrorObject {39/** Error type identifier */40type: string;41/** Human-readable error message */42message: string;43}44```4546### HTTP Status Error Types4748Specific error classes for different HTTP status codes with targeted handling strategies.4950```typescript { .api }51/**52* 400 Bad Request - Invalid request parameters53*/54class BadRequestError extends APIError {55status: 400;56}5758/**59* 401 Unauthorized - Authentication failure60*/61class AuthenticationError extends APIError {62status: 401;63}6465/**66* 403 Forbidden - Insufficient permissions67*/68class PermissionDeniedError extends APIError {69status: 403;70}7172/**73* 404 Not Found - Resource not found74*/75class NotFoundError extends APIError {76status: 404;77}7879/**80* 409 Conflict - Request conflicts with current state81*/82class ConflictError extends APIError {83status: 409;84}8586/**87* 422 Unprocessable Entity - Valid request but server cannot process88*/89class UnprocessableEntityError extends APIError {90status: 422;91}9293/**94* 429 Too Many Requests - Rate limit exceeded95*/96class RateLimitError extends APIError {97status: 429;98}99100/**101* 500 Internal Server Error - Server-side error102*/103class InternalServerError extends APIError {104status: 500;105}106```107108### Connection Error Types109110Errors related to network connectivity and request lifecycle.111112```typescript { .api }113/**114* Network connection failed115*/116class APIConnectionError extends AnthropicError {117/** Underlying network error */118cause: Error;119}120121/**122* Request timed out123*/124class APIConnectionTimeoutError extends APIConnectionError {125/** Timeout duration in milliseconds */126timeout: number;127}128129/**130* Request was aborted by user131*/132class APIUserAbortError extends APIConnectionError {133/** Abort signal that triggered the error */134signal: AbortSignal;135}136```137138## Error Handling Patterns139140### Basic Error Handling141142Handle common API errors with appropriate recovery strategies.143144**Usage Examples:**145146```typescript147import Anthropic, {148AnthropicError,149AuthenticationError,150RateLimitError,151BadRequestError,152APIConnectionError153} from "@anthropic-ai/sdk";154155const client = new Anthropic();156157try {158const message = await client.messages.create({159model: "claude-3-sonnet-20240229",160max_tokens: 1024,161messages: [{ role: "user", content: "Hello!" }],162});163} catch (error) {164if (error instanceof AuthenticationError) {165console.error("Authentication failed - check your API key");166// Redirect to authentication setup167} else if (error instanceof RateLimitError) {168console.error("Rate limit exceeded - implementing backoff");169// Implement exponential backoff retry170await sleep(5000);171// Retry the request172} else if (error instanceof BadRequestError) {173console.error("Invalid request parameters:", error.message);174// Fix request parameters and retry175} else if (error instanceof APIConnectionError) {176console.error("Network connection failed:", error.cause);177// Check network connectivity, retry with timeout178} else if (error instanceof AnthropicError) {179console.error("Anthropic SDK error:", error.message);180// Handle other SDK-specific errors181} else {182console.error("Unexpected error:", error);183// Handle unexpected errors184}185}186```187188### Rate Limit Handling189190Implement sophisticated rate limit handling with exponential backoff.191192```typescript { .api }193/**194* Rate limit error with retry information195*/196interface RateLimitInfo {197/** Requests per minute limit */198limit: number;199/** Remaining requests in current window */200remaining: number;201/** Time when rate limit resets (Unix timestamp) */202reset: number;203/** Recommended retry delay in seconds */204retryAfter?: number;205}206```207208**Usage Examples:**209210```typescript211async function withRateLimitRetry<T>(212operation: () => Promise<T>,213maxRetries: number = 3214): Promise<T> {215let attempt = 0;216217while (attempt < maxRetries) {218try {219return await operation();220} catch (error) {221if (error instanceof RateLimitError) {222const retryAfter = error.headers.get("retry-after");223const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, attempt) * 1000;224225console.log(`Rate limited. Retrying in ${delay}ms...`);226await sleep(delay);227attempt++;228} else {229throw error; // Re-throw non-rate-limit errors230}231}232}233234throw new Error(`Max retries (${maxRetries}) exceeded for rate-limited request`);235}236237// Usage238const message = await withRateLimitRetry(() =>239client.messages.create({240model: "claude-3-sonnet-20240229",241max_tokens: 1024,242messages: [{ role: "user", content: "Hello!" }],243})244);245```246247### Timeout and Abort Handling248249Handle request timeouts and user-initiated cancellations.250251**Usage Examples:**252253```typescript254// Request with custom timeout255const controller = new AbortController();256const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout257258try {259const message = await client.messages.create(260{261model: "claude-3-sonnet-20240229",262max_tokens: 1024,263messages: [{ role: "user", content: "Complex task..." }],264},265{266fetchOptions: { signal: controller.signal },267timeout: 30000,268}269);270clearTimeout(timeoutId);271} catch (error) {272if (error instanceof APIUserAbortError) {273console.log("Request was cancelled by user");274} else if (error instanceof APIConnectionTimeoutError) {275console.log(`Request timed out after ${error.timeout}ms`);276// Retry with longer timeout or different strategy277}278}279280// Streaming with cancellation281const stream = client.messages.stream({282model: "claude-3-sonnet-20240229",283max_tokens: 1024,284messages: [{ role: "user", content: "Long response..." }],285});286287// Cancel stream after user action288document.getElementById("cancel").onclick = () => {289stream.controller.abort();290};291292try {293for await (const event of stream) {294console.log(event);295}296} catch (error) {297if (error instanceof APIUserAbortError) {298console.log("Stream cancelled by user");299}300}301```302303### Validation Error Handling304305Handle parameter validation and request formatting errors.306307**Usage Examples:**308309```typescript310try {311const message = await client.messages.create({312model: "claude-3-sonnet-20240229",313max_tokens: -1, // Invalid parameter314messages: [], // Empty messages array315});316} catch (error) {317if (error instanceof BadRequestError) {318console.error("Request validation failed:");319console.error("Status:", error.status);320console.error("Message:", error.message);321322if (error.error) {323console.error("Error type:", error.error.type);324console.error("Details:", error.error.message);325}326327// Fix validation issues328const validMessage = await client.messages.create({329model: "claude-3-sonnet-20240229",330max_tokens: 1024, // Valid parameter331messages: [{ role: "user", content: "Valid message" }], // Valid messages332});333}334}335```336337### Beta Error Handling338339Handle beta-specific errors and feature availability issues.340341```typescript { .api }342/**343* Beta-specific error types344*/345class BetaError extends AnthropicError {}346class BetaAPIError extends BetaError {347status: number;348error: BetaErrorResponse;349}350class BetaInvalidRequestError extends BetaAPIError {}351class BetaNotFoundError extends BetaAPIError {}352class BetaPermissionError extends BetaAPIError {}353354interface BetaErrorResponse {355type: string;356message: string;357}358```359360**Usage Examples:**361362```typescript363import { BetaError, BetaPermissionError } from "@anthropic-ai/sdk";364365try {366const betaResult = await client.beta.messages.create({367model: "claude-3-5-sonnet-20241022",368max_tokens: 1024,369messages: [{ role: "user", content: "Beta feature test" }],370betas: ["experimental-feature-2024"],371});372} catch (error) {373if (error instanceof BetaPermissionError) {374console.error("No access to beta feature - request access");375// Fall back to stable API376return client.messages.create({377model: "claude-3-sonnet-20240229",378max_tokens: 1024,379messages: [{ role: "user", content: "Beta feature test" }],380});381} else if (error instanceof BetaError) {382console.error("Beta feature error:", error.message);383// Handle beta-specific issues384}385}386```387388## Error Context and Debugging389390### Error Information Access391392Extract detailed information from errors for debugging and logging.393394**Usage Examples:**395396```typescript397try {398const message = await client.messages.create(params);399} catch (error) {400if (error instanceof APIError) {401// Log comprehensive error details402console.error("API Error Details:", {403status: error.status,404message: error.message,405type: error.error?.type,406headers: Object.fromEntries(error.headers.entries()),407requestId: error.headers.get("request-id"),408});409410// Access raw response for debugging411if (error.request) {412console.error("Request URL:", error.request.url);413console.error("Request Method:", error.request.method);414}415}416}417```418419### Custom Error Handling420421Create custom error handlers and recovery strategies.422423**Usage Examples:**424425```typescript426class AnthropicAPIHandler {427private client: Anthropic;428private retryConfig: RetryConfig;429430constructor(client: Anthropic, retryConfig: RetryConfig = {}) {431this.client = client;432this.retryConfig = { maxRetries: 3, baseDelay: 1000, ...retryConfig };433}434435async createMessage(params: MessageCreateParams): Promise<Message> {436return this.withErrorHandling(() =>437this.client.messages.create(params)438);439}440441private async withErrorHandling<T>(operation: () => Promise<T>): Promise<T> {442let lastError: Error;443444for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {445try {446return await operation();447} catch (error) {448lastError = error;449450if (this.shouldRetry(error, attempt)) {451const delay = this.calculateDelay(attempt);452await this.sleep(delay);453continue;454}455456throw this.enrichError(error);457}458}459460throw lastError;461}462463private shouldRetry(error: unknown, attempt: number): boolean {464if (attempt >= this.retryConfig.maxRetries) return false;465466return error instanceof RateLimitError ||467error instanceof APIConnectionTimeoutError ||468error instanceof InternalServerError;469}470471private calculateDelay(attempt: number): number {472return this.retryConfig.baseDelay * Math.pow(2, attempt);473}474475private enrichError(error: unknown): Error {476if (error instanceof APIError) {477const enriched = new Error(478`Anthropic API Error: ${error.message} (Status: ${error.status})`479);480enriched.cause = error;481return enriched;482}483484return error instanceof Error ? error : new Error(String(error));485}486487private sleep(ms: number): Promise<void> {488return new Promise(resolve => setTimeout(resolve, ms));489}490}491492interface RetryConfig {493maxRetries?: number;494baseDelay?: number;495}496```497498## Error Prevention499500### Input Validation501502Validate parameters before making API calls to prevent common errors.503504**Usage Examples:**505506```typescript507function validateMessageParams(params: MessageCreateParams): void {508if (!params.model) {509throw new Error("Model is required");510}511512if (!params.messages || params.messages.length === 0) {513throw new Error("At least one message is required");514}515516if (params.max_tokens <= 0) {517throw new Error("max_tokens must be positive");518}519520if (params.temperature !== undefined && (params.temperature < 0 || params.temperature > 1)) {521throw new Error("temperature must be between 0 and 1");522}523}524525// Usage526try {527validateMessageParams(messageParams);528const message = await client.messages.create(messageParams);529} catch (error) {530console.error("Validation error:", error.message);531}532```533534### Health Checks535536Implement health checks to verify API connectivity and authentication.537538**Usage Examples:**539540```typescript541async function checkAPIHealth(client: Anthropic): Promise<boolean> {542try {543await client.models.list({ limit: 1 });544return true;545} catch (error) {546if (error instanceof AuthenticationError) {547console.error("Authentication failed - check API key");548} else if (error instanceof APIConnectionError) {549console.error("Connection failed - check network");550}551return false;552}553}554555// Usage556if (await checkAPIHealth(client)) {557console.log("API is healthy");558} else {559console.log("API health check failed");560}561```