(
error: unknown,
model: string,
options?: {
messages?: Message[]
messagesForAPI?: (UserMessage | AssistantMessage)[]
},
)
| 423 | } |
| 424 | |
| 425 | export function getAssistantMessageFromError( |
| 426 | error: unknown, |
| 427 | model: string, |
| 428 | options?: { |
| 429 | messages?: Message[] |
| 430 | messagesForAPI?: (UserMessage | AssistantMessage)[] |
| 431 | }, |
| 432 | ): AssistantMessage { |
| 433 | // Check for SDK timeout errors |
| 434 | if ( |
| 435 | error instanceof APIConnectionTimeoutError || |
| 436 | (error instanceof APIConnectionError && |
| 437 | error.message.toLowerCase().includes('timeout')) |
| 438 | ) { |
| 439 | return createAssistantAPIErrorMessage({ |
| 440 | content: API_TIMEOUT_ERROR_MESSAGE, |
| 441 | error: 'unknown', |
| 442 | }) |
| 443 | } |
| 444 | |
| 445 | // Check for image size/resize errors (thrown before API call during validation) |
| 446 | // Use getImageTooLargeErrorMessage() to show "esc esc" hint for CLI users |
| 447 | // but a generic message for SDK users (non-interactive mode) |
| 448 | if (error instanceof ImageSizeError || error instanceof ImageResizeError) { |
| 449 | return createAssistantAPIErrorMessage({ |
| 450 | content: getImageTooLargeErrorMessage(), |
| 451 | }) |
| 452 | } |
| 453 | |
| 454 | // Check for emergency capacity off switch for Opus PAYG users |
| 455 | if ( |
| 456 | error instanceof Error && |
| 457 | error.message.includes(CUSTOM_OFF_SWITCH_MESSAGE) |
| 458 | ) { |
| 459 | return createAssistantAPIErrorMessage({ |
| 460 | content: CUSTOM_OFF_SWITCH_MESSAGE, |
| 461 | error: 'rate_limit', |
| 462 | }) |
| 463 | } |
| 464 | |
| 465 | if ( |
| 466 | error instanceof APIError && |
| 467 | error.status === 429 && |
| 468 | shouldProcessRateLimits(isClaudeAISubscriber()) |
| 469 | ) { |
| 470 | // Check if this is the new API with multiple rate limit headers |
| 471 | const rateLimitType = error.headers?.get?.( |
| 472 | 'anthropic-ratelimit-unified-representative-claim', |
| 473 | ) as 'five_hour' | 'seven_day' | 'seven_day_opus' | null |
| 474 | |
| 475 | const overageStatus = error.headers?.get?.( |
| 476 | 'anthropic-ratelimit-unified-overage-status', |
| 477 | ) as 'allowed' | 'allowed_warning' | 'rejected' | null |
| 478 | |
| 479 | // If we have the new headers, use the new message generation |
| 480 | if (rateLimitType || overageStatus) { |
| 481 | // Build limits object from error headers to determine the appropriate message |
| 482 | const limits: ClaudeAILimits = { |
no test coverage detected