fix(external-image): hide model details in API-facing generation errors

This commit is contained in:
Your Name 2026-06-09 18:44:03 +08:00
parent aebf5e86cc
commit 79751743f2
2 changed files with 50 additions and 8 deletions

View File

@ -8,6 +8,7 @@ import {
authenticateExternalImageApiRequest,
buildExternalImageApiModelCandidates,
buildExternalImageApiKeyFingerprint,
ExternalImageApiGenerationError,
ensureHostedReferenceImageUrls,
generateImagesWithFailover,
getRequesterIp,
@ -405,6 +406,17 @@ export async function POST(request: Request) {
});
} catch (error) {
console.error("[External Image API] Generate failed:", error);
const shouldHideModelInfo = error instanceof ExternalImageApiGenerationError;
const internalError = shouldHideModelInfo
? error.internalMessage
: error instanceof Error
? error.message
: "图片生成失败";
const publicError = shouldHideModelInfo
? error.userMessage
: error instanceof Error
? error.message
: "图片生成失败";
if (error instanceof z.ZodError) {
return NextResponse.json(
@ -421,9 +433,16 @@ export async function POST(request: Request) {
.update(externalImageApiRequestLog)
.set({
status: "failed",
errorMessage: error instanceof Error ? error.message : "图片生成失败",
errorMessage: internalError,
responsePayload: {
error: error instanceof Error ? error.message : "图片生成失败",
error: shouldHideModelInfo
? {
message: error.userMessage,
attempts: error.attempts,
internalError,
}
: internalError,
attempts: shouldHideModelInfo ? error.attempts : undefined,
},
durationMs: Date.now() - startedAt,
completedAt: new Date(),
@ -449,7 +468,7 @@ export async function POST(request: Request) {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : "图片生成失败",
error: publicError,
},
{ status: 500 },
);

View File

@ -24,6 +24,30 @@ type ExternalImageApiGenerateAttempt = {
error?: string;
};
export class ExternalImageApiGenerationError extends Error {
readonly attempts: ExternalImageApiGenerateAttempt[];
readonly userMessage: string;
constructor(
attempts: ExternalImageApiGenerateAttempt[],
userMessage = "图片生成失败,请稍后重试",
) {
const summary = attempts
.filter((attempt) => !attempt.success)
.map((attempt) => attempt.displayName || attempt.modelRuntimeId)
.join("; ");
super(summary || "所有候选模型均调用失败");
this.name = "ExternalImageApiGenerationError";
this.attempts = attempts;
this.userMessage = userMessage;
}
get internalMessage() {
return this.message;
}
}
type ExternalImageApiGeneratedImage = {
id: number;
originalUrl: string;
@ -759,11 +783,10 @@ export async function generateImagesWithFailover(params: {
}
}
const summary = attempts
.filter((item) => !item.success)
.map((item) => `${item.displayName}: ${item.error || "图片生成失败"}`)
.join(";");
throw new Error(summary || "所有候选生图模型均调用失败");
throw new ExternalImageApiGenerationError(
attempts,
"外部生图服务暂无可用模型返回,请稍后重试",
);
}
export async function ensureHostedReferenceImageUrls(imageUrls: string[]) {