fix(frontend/copilot): parse JSON error body for structured 429 detection in useCopilotStream

This commit is contained in:
Zamil Majdy
2026-03-16 06:19:12 +07:00
parent 1456659dba
commit e71979e0b2

View File

@@ -179,14 +179,28 @@ export function useCopilotStream({
if (!sessionId) return;
// Detect rate limit (429) responses and show reset time to the user.
const isRateLimited =
error.message.includes("429") ||
error.message.toLowerCase().includes("usage limit");
// The SDK throws a plain Error whose message is the raw response body
// (FastAPI returns {"detail": "...usage limit..."} for 429s).
let errorDetail: string = error.message;
try {
const parsed = JSON.parse(error.message) as unknown;
if (
typeof parsed === "object" &&
parsed !== null &&
"detail" in parsed &&
typeof (parsed as { detail: unknown }).detail === "string"
) {
errorDetail = (parsed as { detail: string }).detail;
}
} catch {
// Not JSON — use message as-is
}
const isRateLimited = errorDetail.toLowerCase().includes("usage limit");
if (isRateLimited) {
toast({
title: "Usage limit reached",
description:
error.message.replace(/^[^:]*:\s*/, "") ||
errorDetail ||
"You've reached your usage limit. Please try again later.",
variant: "destructive",
});
@@ -195,10 +209,10 @@ export function useCopilotStream({
// Detect authentication failures (from getAuthHeaders or 401 responses)
const isAuthError =
error.message.includes("Authentication failed") ||
error.message.includes("Unauthorized") ||
error.message.includes("Not authenticated") ||
error.message.toLowerCase().includes("401");
errorDetail.includes("Authentication failed") ||
errorDetail.includes("Unauthorized") ||
errorDetail.includes("Not authenticated") ||
errorDetail.toLowerCase().includes("401");
if (isAuthError) {
toast({
title: "Authentication error",