diff --git a/backend/src/routes/aiCategorization.ts b/backend/src/routes/aiCategorization.ts index 80eb663..1791a10 100644 --- a/backend/src/routes/aiCategorization.ts +++ b/backend/src/routes/aiCategorization.ts @@ -39,9 +39,12 @@ function runOut(run: AiCategorizationRun | null) { }; } +// Provider errors already have the API key redacted, so the reason is safe to pass on. function aiFailure(error: unknown): never { if (error instanceof HttpError) throw error; - throw new HttpError(502, "AI provider failed", "ai_failed"); + const reason = error instanceof Error ? error.message : String(error); + console.warn("AI categorization failed:", reason); + throw new HttpError(502, `AI provider failed: ${reason}`, "ai_failed"); } router.get( diff --git a/backend/tests/aiCategorization.test.ts b/backend/tests/aiCategorization.test.ts index 4857212..152ce48 100644 --- a/backend/tests/aiCategorization.test.ts +++ b/backend/tests/aiCategorization.test.ts @@ -326,6 +326,7 @@ describe("AI categorization", () => { const timeout = await request(app).post(`/api/print/${timedOut.id}/recategorize`).set(auth()).send({}); expect(timeout.status).toBe(502); expect(timeout.body.code).toBe("ai_failed"); + expect(timeout.body.error).toBe("AI provider failed: The AI provider did not answer within 0 s"); expect(providerRequests).toBe(3); await stopProvider(); @@ -344,6 +345,7 @@ describe("AI categorization", () => { const notRetried = await request(app).post(`/api/print/${badRequest.id}/recategorize`).set(auth()).send({}); expect(notRetried.status).toBe(502); expect(notRetried.body.code).toBe("ai_failed"); + expect(notRetried.body.error).toBe("AI provider failed: AI provider returned HTTP 400"); expect(providerRequests).toBe(1); expect(target.id).toBeTruthy(); });