From ccdd0cfefb02df80e7c3bb4f780ab32e27442905 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Mon, 3 Aug 2026 14:42:53 +0530 Subject: [PATCH] fix(chat-error-classifier): prefer the backend-composed provider message --- .../lib/chat/chat-error-classifier.ts | 46 +++++++++++++++---- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/surfsense_web/lib/chat/chat-error-classifier.ts b/surfsense_web/lib/chat/chat-error-classifier.ts index f1d199bf0..a99aafc04 100644 --- a/surfsense_web/lib/chat/chat-error-classifier.ts +++ b/surfsense_web/lib/chat/chat-error-classifier.ts @@ -103,6 +103,22 @@ function parseEmbeddedJson(text: string): Record | null { return null; } +/** + * Prefer the message the backend composed for provider-classified errors. + * + * The stream classifier already tailors these strings to the situation (which + * knob to turn for an LM Studio context rejection, for instance), so replacing + * them client-side hides the actionable half. Falls back to the generic string + * when the code arrives from a non-stream path, whose body is an HTTP sentinel + * or a raw provider dump rather than prose. + */ +export function preferBackendMessage(rawMessage: string, fallback: string): string { + const trimmed = rawMessage.trim(); + if (!trimmed || trimmed.length > 300) return fallback; + if (trimmed.includes("{") || trimmed.startsWith("Backend error:")) return fallback; + return trimmed; +} + function inferProviderErrorType(parsedJson: Record | null): string | undefined { if (!parsedJson) return undefined; const topLevelType = parsedJson.type; @@ -217,8 +233,10 @@ export function classifyChatError(input: RawChatErrorInput): NormalizedChatError severity: "warn", telemetryEvent: "chat_blocked", isExpected: true, - userMessage: - "This model’s API key is invalid or expired. Switch models, or update the API key.", + userMessage: preferBackendMessage( + rawMessage, + "This model’s API key is invalid or expired. Switch models, or update the API key." + ), rawMessage, errorCode: errorCode ?? "MODEL_AUTH_FAILED", details: { flow: input.flow, providerErrorType }, @@ -232,8 +250,10 @@ export function classifyChatError(input: RawChatErrorInput): NormalizedChatError severity: "warn", telemetryEvent: "chat_blocked", isExpected: true, - userMessage: - "This model is unavailable or no longer exists. Switch to another model and try again.", + userMessage: preferBackendMessage( + rawMessage, + "This model is unavailable or no longer exists. Switch to another model and try again." + ), rawMessage, errorCode: errorCode ?? "MODEL_NOT_FOUND", details: { flow: input.flow, providerErrorType }, @@ -247,8 +267,10 @@ export function classifyChatError(input: RawChatErrorInput): NormalizedChatError severity: "warn", telemetryEvent: "chat_blocked", isExpected: true, - userMessage: - "This request is too large for the selected model. Reduce the input or switch models.", + userMessage: preferBackendMessage( + rawMessage, + "This request is too large for the selected model. Reduce the input or switch models." + ), rawMessage, errorCode: errorCode ?? "MODEL_CONTEXT_LIMIT", details: { flow: input.flow, providerErrorType }, @@ -262,8 +284,10 @@ export function classifyChatError(input: RawChatErrorInput): NormalizedChatError severity: "warn", telemetryEvent: "chat_blocked", isExpected: true, - userMessage: - "The selected model provider is temporarily unavailable. Please try again or switch models.", + userMessage: preferBackendMessage( + rawMessage, + "The selected model provider is temporarily unavailable. Please try again or switch models." + ), rawMessage, errorCode: errorCode ?? "MODEL_PROVIDER_UNAVAILABLE", details: { flow: input.flow, providerErrorType }, @@ -277,8 +301,10 @@ export function classifyChatError(input: RawChatErrorInput): NormalizedChatError severity: "warn", telemetryEvent: "chat_blocked", isExpected: true, - userMessage: - "This model is temporarily rate-limited. Please try again in a few seconds or switch models.", + userMessage: preferBackendMessage( + rawMessage, + "This model is temporarily rate-limited. Please try again in a few seconds or switch models." + ), rawMessage, errorCode: errorCode ?? "RATE_LIMITED", details: { flow: input.flow, providerErrorType },