(
error: unknown,
model: string,
options?: {
messages?: Message[]
messagesForAPI?: (UserMessage | AssistantMessage)[]
},
)
| 472 | } |
| 473 | |
| 474 | export function getAssistantMessageFromError( |
| 475 | error: unknown, |
| 476 | model: string, |
| 477 | options?: { |
| 478 | messages?: Message[] |
| 479 | messagesForAPI?: (UserMessage | AssistantMessage)[] |
| 480 | }, |
| 481 | ): AssistantMessage { |
| 482 | // Check for SDK timeout errors |
| 483 | if ( |
| 484 | error instanceof APIConnectionTimeoutError || |
| 485 | (error instanceof APIConnectionError && |
| 486 | error.message.toLowerCase().includes('timeout')) |
| 487 | ) { |
| 488 | return createAssistantAPIErrorMessage({ |
| 489 | content: API_TIMEOUT_ERROR_MESSAGE, |
| 490 | error: 'unknown', |
| 491 | }) |
| 492 | } |
| 493 | |
| 494 | // Check for image size/resize errors (thrown before API call during validation) |
| 495 | // Use getImageTooLargeErrorMessage() to show "esc esc" hint for CLI users |
| 496 | // but a generic message for SDK users (non-interactive mode) |
| 497 | if (error instanceof ImageSizeError || error instanceof ImageResizeError) { |
| 498 | return createAssistantAPIErrorMessage({ |
| 499 | content: getImageTooLargeErrorMessage(), |
| 500 | }) |
| 501 | } |
| 502 | |
| 503 | // Check for emergency capacity off switch for Opus PAYG users |
| 504 | if ( |
| 505 | error instanceof Error && |
| 506 | error.message.includes(CUSTOM_OFF_SWITCH_MESSAGE) |
| 507 | ) { |
| 508 | return createAssistantAPIErrorMessage({ |
| 509 | content: CUSTOM_OFF_SWITCH_MESSAGE, |
| 510 | error: 'rate_limit', |
| 511 | }) |
| 512 | } |
| 513 | |
| 514 | if ( |
| 515 | error instanceof APIError && |
| 516 | error.status === 429 && |
| 517 | shouldProcessRateLimits(hasCurrentOauthBackedFirstPartyErrorSession()) |
| 518 | ) { |
| 519 | // Check if this is the new API with multiple rate limit headers |
| 520 | const rateLimitType = error.headers?.get?.( |
| 521 | 'anthropic-ratelimit-unified-representative-claim', |
| 522 | ) as 'five_hour' | 'seven_day' | 'seven_day_opus' | null |
| 523 | |
| 524 | const overageStatus = error.headers?.get?.( |
| 525 | 'anthropic-ratelimit-unified-overage-status', |
| 526 | ) as 'allowed' | 'allowed_warning' | 'rejected' | null |
| 527 | |
| 528 | // If we have the new headers, use the new message generation |
| 529 | if (rateLimitType || overageStatus) { |
| 530 | // Build limits object from error headers to determine the appropriate message |
| 531 | const limits: ClaudeAILimits = { |
no test coverage detected