fix(confidence-engine): log case-start failures
This commit is contained in:
@@ -16,10 +16,25 @@ export async function POST(request) {
|
||||
? result.statusCode
|
||||
: 500;
|
||||
|
||||
const diagnostics = {
|
||||
status,
|
||||
error: result.error ?? "Start case failed",
|
||||
validationErrors: result.validationErrors,
|
||||
analysisErrors: result.analysisErrors,
|
||||
validationIssues: result.validationIssues,
|
||||
rawResponse: result.rawResponse ?? undefined,
|
||||
};
|
||||
|
||||
if (status >= 500) {
|
||||
console.error("[api/cases/start] error response", diagnostics);
|
||||
} else {
|
||||
console.warn("[api/cases/start] error response", diagnostics);
|
||||
}
|
||||
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
error: result.error ?? "Start case failed",
|
||||
error: diagnostics.error,
|
||||
validationErrors: result.validationErrors,
|
||||
diagnostics: result.diagnostics,
|
||||
analysisErrors: result.analysisErrors,
|
||||
@@ -28,7 +43,12 @@ export async function POST(request) {
|
||||
},
|
||||
{ status },
|
||||
);
|
||||
} catch {
|
||||
} catch (error) {
|
||||
console.error("[api/cases/start] unhandled exception", {
|
||||
message: error instanceof Error ? error.message : String(error),
|
||||
stack: error instanceof Error ? error.stack : undefined,
|
||||
error,
|
||||
});
|
||||
return Response.json(
|
||||
{
|
||||
success: false,
|
||||
|
||||
@@ -57,6 +57,12 @@
|
||||
- This is a generation-time relationship-reference integrity defect. v0.5 now requires semantic units before relationships and exact reuse of emitted endpoint IDs; legitimate missing endpoint concepts must be materialised first under existing provenance rules.
|
||||
- The builder remains unchanged. Live compliance remains untested; next restart point is one production-default relationship-reference-integrity validation.
|
||||
|
||||
## Case-start error logging
|
||||
|
||||
- The latest live validation was blocked by an HTTP 500 route-level exception with generic client output. `/api/cases/start` now writes structured Next.js server-console diagnostics for every route-owned error response: 4xx at warning level and 5xx/502 at error level.
|
||||
- Caught exceptions log their actual exception, message, and stack while the client response remains generic; successful responses are not logged. No reasoning, status, or response semantics changed.
|
||||
- Next restart point: one production-default manufacturing call while observing the Next.js dev-server terminal.
|
||||
|
||||
## Current product architecture
|
||||
|
||||
Three distinct routes, not a single page:
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const mockStartCase = vi.fn();
|
||||
let warnSpy;
|
||||
let errorSpy;
|
||||
|
||||
vi.mock("@/lib/graph/orchestrator.js", () => ({
|
||||
startCase: (...args) => mockStartCase(...args),
|
||||
@@ -10,6 +12,13 @@ describe("app/api/cases/start route", () => {
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
vi.clearAllMocks();
|
||||
warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
warnSpy.mockRestore();
|
||||
errorSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("delegates request body to the orchestrator", async () => {
|
||||
@@ -78,6 +87,8 @@ describe("app/api/cases/start route", () => {
|
||||
success: true,
|
||||
reconstruction,
|
||||
});
|
||||
expect(warnSpy).not.toHaveBeenCalled();
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns 400 for invalid request input", async () => {
|
||||
@@ -102,6 +113,12 @@ describe("app/api/cases/start route", () => {
|
||||
success: false,
|
||||
error: "Invalid start-case request",
|
||||
});
|
||||
expect(warnSpy).toHaveBeenCalledTimes(1);
|
||||
expect(warnSpy).toHaveBeenCalledWith(
|
||||
"[api/cases/start] error response",
|
||||
expect.objectContaining({ status: 400, error: "Invalid start-case request" }),
|
||||
);
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns provider/internal failures as 5xx without stack traces", async () => {
|
||||
@@ -148,6 +165,18 @@ describe("app/api/cases/start route", () => {
|
||||
received: "undefined",
|
||||
}),
|
||||
]);
|
||||
expect(errorSpy).toHaveBeenCalledTimes(1);
|
||||
expect(errorSpy).toHaveBeenCalledWith(
|
||||
"[api/cases/start] error response",
|
||||
expect.objectContaining({
|
||||
status: 502,
|
||||
error: "Provider unavailable",
|
||||
analysisErrors: ["reconstruction: Required"],
|
||||
validationIssues: expect.any(Array),
|
||||
rawResponse,
|
||||
}),
|
||||
);
|
||||
expect(warnSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns structured 500 on malformed JSON", async () => {
|
||||
@@ -163,5 +192,13 @@ describe("app/api/cases/start route", () => {
|
||||
success: false,
|
||||
error: "Internal server error",
|
||||
});
|
||||
expect(errorSpy).toHaveBeenCalledWith(
|
||||
"[api/cases/start] unhandled exception",
|
||||
expect.objectContaining({
|
||||
message: "Unexpected token",
|
||||
stack: expect.any(String),
|
||||
error: expect.any(Error),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user