| 505 | |
| 506 | // Helper to categorize errors and return appropriate response |
| 507 | function handleError(error: unknown): Response { |
| 508 | console.error("Error in chat route:", error) |
| 509 | |
| 510 | const isDev = process.env.NODE_ENV === "development" |
| 511 | |
| 512 | // Check for specific AI SDK error types |
| 513 | if (APICallError.isInstance(error)) { |
| 514 | return Response.json( |
| 515 | { |
| 516 | error: error.message, |
| 517 | ...(isDev && { |
| 518 | details: error.responseBody, |
| 519 | stack: error.stack, |
| 520 | }), |
| 521 | }, |
| 522 | { status: error.statusCode || 500 }, |
| 523 | ) |
| 524 | } |
| 525 | |
| 526 | if (LoadAPIKeyError.isInstance(error)) { |
| 527 | return Response.json( |
| 528 | { |
| 529 | error: "Authentication failed. Please check your API key.", |
| 530 | ...(isDev && { |
| 531 | stack: error.stack, |
| 532 | }), |
| 533 | }, |
| 534 | { status: 401 }, |
| 535 | ) |
| 536 | } |
| 537 | |
| 538 | // Fallback for other errors with safety filter |
| 539 | const message = |
| 540 | error instanceof Error ? error.message : "An unexpected error occurred" |
| 541 | const status = (error as any)?.statusCode || (error as any)?.status || 500 |
| 542 | |
| 543 | // Prevent leaking API keys, tokens, or other sensitive data |
| 544 | const lowerMessage = message.toLowerCase() |
| 545 | const safeMessage = |
| 546 | lowerMessage.includes("key") || |
| 547 | lowerMessage.includes("token") || |
| 548 | lowerMessage.includes("sig") || |
| 549 | lowerMessage.includes("signature") || |
| 550 | lowerMessage.includes("secret") || |
| 551 | lowerMessage.includes("password") || |
| 552 | lowerMessage.includes("credential") |
| 553 | ? "Authentication failed. Please check your credentials." |
| 554 | : message |
| 555 | |
| 556 | return Response.json( |
| 557 | { |
| 558 | error: safeMessage, |
| 559 | ...(isDev && { |
| 560 | details: message, |
| 561 | stack: error instanceof Error ? error.stack : undefined, |
| 562 | }), |
| 563 | }, |
| 564 | { status }, |