fix: handle SnapGen image task failures

This commit is contained in:
134 2026-06-24 21:51:12 +08:00
parent 4de04234d0
commit 28c5965c52
2 changed files with 75 additions and 6 deletions

View File

@ -374,9 +374,23 @@ function extractErrorMessage(payload: any): string {
payload?.detail?.error_message ||
payload?.detail?.error ||
payload?.detail?.message ||
payload?.detail?.status_desc ||
payload?.data?.error_message ||
payload?.data?.error?.message ||
payload?.data?.error ||
payload?.data?.message ||
payload?.data?.msg ||
payload?.data?.status_desc ||
payload?.data?.state_detail ||
payload?.data?.err_message ||
payload?.data?.err_info ||
payload?.error_message ||
payload?.error?.message ||
payload?.error ||
payload?.status_desc ||
payload?.state_detail ||
payload?.err_message ||
payload?.err_info ||
payload?.message ||
payload?.msg ||
"SnapGen 任务执行失败"
@ -808,7 +822,13 @@ async function buildRequestForm({
}
}
async function waitForHistoryResult(baseURL: string, apiKey: string, uuid: string, sourceUrls: string[]) {
async function waitForHistoryResult(
baseURL: string,
apiKey: string,
uuid: string,
sourceUrls: string[],
context: { apiFormat: SnapgenApiFormat; model: string }
) {
for (let attempt = 1; attempt <= POLL_MAX_ATTEMPTS; attempt++) {
const response = await fetch(
joinApiPath(baseURL, `/uapi/v1/history/${encodeURIComponent(uuid)}`),
@ -818,7 +838,17 @@ async function waitForHistoryResult(baseURL: string, apiKey: string, uuid: strin
if (!response.ok) {
if (attempt === POLL_MAX_ATTEMPTS) {
throw new Error(`${extractErrorMessage(payload)} (HTTP ${response.status})`);
const errorMessage = extractErrorMessage(payload);
console.error("[SnapGen Image] History request failed:", {
uuid,
model: context.model,
apiFormat: context.apiFormat,
attempt,
status: response.status,
error: errorMessage,
responseSnippet: compactPayloadSnippet(payload),
});
throw new Error(`${errorMessage} (HTTP ${response.status})`);
}
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
continue;
@ -832,9 +862,27 @@ async function waitForHistoryResult(baseURL: string, apiKey: string, uuid: strin
const statusCode = extractStatusCode(payload);
if (statusCode === 3) {
throw new Error(extractErrorMessage(payload));
const errorMessage = extractErrorMessage(payload);
console.error("[SnapGen Image] History task failed:", {
uuid,
model: context.model,
apiFormat: context.apiFormat,
attempt,
statusCode,
error: errorMessage,
responseSnippet: compactPayloadSnippet(payload),
});
throw new Error(errorMessage);
}
if (statusCode === 2) {
console.error("[SnapGen Image] History task completed without images:", {
uuid,
model: context.model,
apiFormat: context.apiFormat,
attempt,
statusCode,
responseSnippet: compactPayloadSnippet(payload),
});
throw new Error("SnapGen 任务已完成但未返回图片地址");
}
@ -920,10 +968,18 @@ export function createSnapgenImage({ apiKey, baseURL }: SnapgenImageConfig) {
formData,
});
let outputUrls: string[] = [];
let base64Images: Array<{ buffer: Buffer; mimeType: string }> = [];
const statusCode = extractStatusCode(createPayload);
const uuid = extractUuid(createPayload);
console.log("[SnapGen Image] Create task response:", {
model: runtimeModelId,
apiFormat,
statusCode,
uuid: uuid || null,
responseSnippet: compactPayloadSnippet(createPayload),
});
let outputUrls: string[] = [];
let base64Images: Array<{ buffer: Buffer; mimeType: string }> = [];
if (statusCode === 3) {
throw new Error(extractErrorMessage(createPayload));
}
@ -939,7 +995,10 @@ export function createSnapgenImage({ apiKey, baseURL }: SnapgenImageConfig) {
`SnapGen 创建任务成功,但未返回 uuid 或图片结果,响应片段: ${compactPayloadSnippet(createPayload)}`
);
}
const historyResult = await waitForHistoryResult(baseURL, apiKey, uuid, imageUrls);
const historyResult = await waitForHistoryResult(baseURL, apiKey, uuid, imageUrls, {
apiFormat,
model: runtimeModelId,
});
outputUrls = historyResult.imageUrls;
base64Images = historyResult.base64Images;
}

View File

@ -238,6 +238,16 @@ export function classifyAiModelHealthFailure(error: unknown): {
export function shouldFailoverAiModelError(error: unknown) {
const classification = classifyAiModelHealthFailure(error);
const normalized = getErrorMessage(error).toLowerCase();
const imageProviderTaskFailed =
normalized.includes("image generation failed") ||
normalized.includes("snapgen 任务执行失败") ||
normalized.includes("snapgen 创建任务成功") ||
normalized.includes("snapgen 任务已完成但未返回图片地址") ||
normalized.includes("snapgen 未返回可用图片");
if (imageProviderTaskFailed) {
return true;
}
if (classification.reason === "user_cancelled" || classification.reason === "non_provider_failure") {
return false;