fix(ai): show why a recategorization failed

The route replaced every provider error with a bare "AI provider failed",
so a stopped Ollama looked the same as a timeout or a bad answer. Pass on the
reason (the API key is already redacted) and log it.
This commit is contained in:
Tautvydas Derzinskas committed 2026-10-11 21:16:48 +02:00
1 parent 29c54bac11
commit 5fcadfb179
2 files changed
+6 -1

No files matched your search

+4 -1
View File
@@ -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(
+2
View File
@@ -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();
});