fix: surface llm workflow errors

This commit is contained in:
Codex
2026-06-21 23:43:03 +08:00
parent 4bb5ca5eb0
commit f1dac15400
12 changed files with 286 additions and 500 deletions
+51 -36
View File
@@ -2,6 +2,7 @@ import { NextResponse } from "next/server";
import { requireApiAccess } from "../../../../../lib/api/auth";
import { getRepositoryFromRuntime } from "../../../../../lib/db/repository";
import { LlmValidationError } from "../../../../../lib/llm/client";
import { getExportStoreFromRuntime } from "../../../../../lib/workflow/export-store";
import { runOptimizationWorkflow } from "../../../../../lib/workflow/orchestrator";
@@ -30,41 +31,55 @@ export async function POST(request: Request, context: RouteContext) {
);
}
const result = await runOptimizationWorkflow({
input: {
title: job.source_title,
body: job.source_body,
images: job.image_inputs,
platform: job.publish_platform,
user_instructions: job.user_instructions,
},
factCard: factCardRecord,
});
const optimizedArticle = await repository.saveOptimizedArticle(jobId, result.article);
const qaReport = await repository.saveQaReport(
jobId,
optimizedArticle.revision ?? 1,
result.qaReport,
);
const exportStore = getExportStoreFromRuntime();
const exportPaths =
qaReport.overall_status === "fail"
? {}
: await exportStore.writeJobExports({
jobId,
article: optimizedArticle,
qaReport,
});
await repository.updateArticleJob(jobId, {
status: qaReport.overall_status === "fail" ? "qa_failed" : "optimized",
export_paths: exportPaths,
});
try {
const result = await runOptimizationWorkflow({
input: {
title: job.source_title,
body: job.source_body,
images: job.image_inputs,
platform: job.publish_platform,
user_instructions: job.user_instructions,
},
factCard: factCardRecord,
});
const optimizedArticle = await repository.saveOptimizedArticle(
jobId,
result.article,
);
const qaReport = await repository.saveQaReport(
jobId,
optimizedArticle.revision ?? 1,
result.qaReport,
);
const exportStore = getExportStoreFromRuntime();
const exportPaths =
qaReport.overall_status === "fail"
? {}
: await exportStore.writeJobExports({
jobId,
article: optimizedArticle,
qaReport,
});
await repository.updateArticleJob(jobId, {
status: qaReport.overall_status === "fail" ? "qa_failed" : "optimized",
export_paths: exportPaths,
});
return NextResponse.json({
optimizedArticle,
qaReport,
exportPaths,
rewriteRounds: result.rewrite_rounds,
stoppedAfterMaxRewrites: result.stopped_after_max_rewrites,
});
return NextResponse.json({
optimizedArticle,
qaReport,
exportPaths,
rewriteRounds: result.rewrite_rounds,
stoppedAfterMaxRewrites: result.stopped_after_max_rewrites,
});
} catch (error) {
const message = error instanceof Error ? error.message : "LLM optimization failed";
return NextResponse.json({ error: message }, { status: getErrorStatus(error) });
}
}
function getErrorStatus(error: unknown) {
if (error instanceof LlmValidationError) return 502;
if (error instanceof Error && /^LLM\b|provider/i.test(error.message)) return 502;
return 500;
}
+8 -1
View File
@@ -2,6 +2,7 @@ import { NextResponse } from "next/server";
import { requireApiAccess } from "../../../lib/api/auth";
import { getRepositoryFromRuntime } from "../../../lib/db/repository";
import { LlmValidationError } from "../../../lib/llm/client";
import { extractCandidateFactCard } from "../../../lib/workflow/fact-extractor";
import { normalizeInput, type RawArticleInput } from "../../../lib/workflow/input-normalizer";
@@ -26,7 +27,7 @@ export async function POST(request: Request) {
return NextResponse.json({ job, candidateFactCard }, { status: 201 });
} catch (error) {
return jsonError(error, 400);
return jsonError(error, getErrorStatus(error));
}
}
@@ -34,3 +35,9 @@ function jsonError(error: unknown, status: number) {
const message = error instanceof Error ? error.message : "Request failed";
return NextResponse.json({ error: message }, { status });
}
function getErrorStatus(error: unknown) {
if (error instanceof LlmValidationError) return 502;
if (error instanceof Error && /^LLM\b|provider/i.test(error.message)) return 502;
return 400;
}