From 32be3a0a88d47260d9577fa7e1c43bb353b37c8c Mon Sep 17 00:00:00 2001 From: Shruc <42489293+P3il4@users.noreply.github.com> Date: Thu, 9 Apr 2026 00:47:02 +0300 Subject: [PATCH] better error reports for chat fallbacks (#2783) --- src/backend/src/api/APIError.js | 5 +++++ .../src/services/ai/chat/AIChatService.ts | 21 ++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/backend/src/api/APIError.js b/src/backend/src/api/APIError.js index 21b1934b2..bdbcbef13 100644 --- a/src/backend/src/api/APIError.js +++ b/src/backend/src/api/APIError.js @@ -61,6 +61,11 @@ class APIError { status: 400, message: ({ delegate, message }) => `Error 400 from delegate ${quot(delegate)}: ${message}`, }, + 'ai_chat_all_providers_failed': { + status: 502, + message: ({ attempts }) => + `All AI chat providers failed (${attempts.length} attempt${attempts.length === 1 ? '' : 's'})`, + }, // Things 'disallowed_thing': { status: 400, diff --git a/src/backend/src/services/ai/chat/AIChatService.ts b/src/backend/src/services/ai/chat/AIChatService.ts index af72e69c4..dfd707891 100644 --- a/src/backend/src/services/ai/chat/AIChatService.ts +++ b/src/backend/src/services/ai/chat/AIChatService.ts @@ -160,7 +160,7 @@ export class AIChatService extends BaseService { }, }; - getModel ({ modelId, provider}: { modelId: string, provider?: string }) { + getModel ({ modelId, provider }: { modelId: string, provider?: string }) { const models = this.#modelIdMap[modelId]; if ( ! models ) { @@ -541,6 +541,7 @@ export class AIChatService extends BaseService { if ( ! provider ) { throw new Error(`no provider found for model ${model.id}`); } + const attempts: { model: string; provider: string; error: string }[] = []; try { res = await provider.complete({ ...parameters, @@ -555,6 +556,11 @@ export class AIChatService extends BaseService { triedProviders.push(model.provider!); let error = e as Error; + attempts.push({ + model: model.id, + provider: model.provider!, + error: error?.message ?? String(e), + }); while ( error ) { @@ -595,7 +601,9 @@ export class AIChatService extends BaseService { const fallback = await this.getFallbackModel(model.id, tried, triedProviders); if ( ! fallback ) { - throw new Error('no fallback model available'); + throw APIError.create('ai_chat_all_providers_failed', null, { + attempts, + }); } const { @@ -642,6 +650,11 @@ export class AIChatService extends BaseService { } catch (e) { console.error('error during fallback selection: ', e); error = e as Error; + attempts.push({ + model: fallBackModel.id, + provider: fallBackModel.provider!, + error: error?.message ?? String(e), + }); } } } @@ -652,7 +665,9 @@ export class AIChatService extends BaseService { const username = actor.type?.user?.username; if ( ! res! ) { - throw new Error('No response from AI chat provider'); + throw APIError.create('ai_chat_all_providers_failed', null, { + attempts, + }); } res.via_ai_chat_service = true; // legacy field always true now