fix: stabilize snapgen reference downloads

This commit is contained in:
134 2026-07-04 15:38:51 +08:00
parent fec71038c5
commit fb11a4becd

View File

@ -45,6 +45,9 @@ type SnapgenApiFormat =
const DEFAULT_OUTPUT_FORMAT = "png";
const POLL_INTERVAL_MS = 2000;
const POLL_MAX_ATTEMPTS = 240;
const REFERENCE_ASPECT_DOWNLOAD_TIMEOUT_MS = 30_000;
const REFERENCE_FILE_DOWNLOAD_TIMEOUT_MS = 90_000;
const REFERENCE_FILE_DOWNLOAD_RETRIES = 2;
function joinApiPath(baseURL: string, path: string) {
const cleanBase = baseURL.replace(/\/+$/, "");
@ -182,7 +185,10 @@ async function inferImageDimensionsFromUrl(
if (!/^https?:\/\//i.test(imageUrl)) return null;
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 20_000);
const timeout = setTimeout(
() => controller.abort(),
REFERENCE_ASPECT_DOWNLOAD_TIMEOUT_MS
);
try {
const response = await fetch(imageUrl, {
cache: "no-store",
@ -663,23 +669,48 @@ async function downloadAndUploadImage(imageUrl: string): Promise<UploadedImage>
}
async function downloadReferenceImageFile(imageUrl: string, index: number) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 20_000);
try {
const response = await fetch(imageUrl, { signal: controller.signal });
if (!response.ok) {
throw new Error(`Failed to download reference image: ${response.status}`);
let lastError: unknown = null;
for (let attempt = 1; attempt <= REFERENCE_FILE_DOWNLOAD_RETRIES + 1; attempt += 1) {
const controller = new AbortController();
const timeout = setTimeout(
() => controller.abort(),
REFERENCE_FILE_DOWNLOAD_TIMEOUT_MS
);
try {
const response = await fetch(imageUrl, { signal: controller.signal });
if (!response.ok) {
throw new Error(`Failed to download reference image: ${response.status}`);
}
const mimeType = response.headers.get("content-type") || "image/png";
const buffer = Buffer.from(await response.arrayBuffer());
const extension = detectImageExtension(imageUrl, mimeType);
return {
blob: new Blob([new Uint8Array(buffer)], { type: mimeType }),
filename: `snapgen-reference-${index + 1}.${extension}`,
};
} catch (error) {
lastError = error;
if (attempt <= REFERENCE_FILE_DOWNLOAD_RETRIES) {
console.warn("[SnapGen Image] Retrying reference image download:", {
attempt,
imageIndex: index + 1,
error: error instanceof Error ? error.message : String(error),
});
await new Promise((resolve) => setTimeout(resolve, attempt * 1500));
continue;
}
} finally {
clearTimeout(timeout);
}
const mimeType = response.headers.get("content-type") || "image/png";
const buffer = Buffer.from(await response.arrayBuffer());
const extension = detectImageExtension(imageUrl, mimeType);
return {
blob: new Blob([new Uint8Array(buffer)], { type: mimeType }),
filename: `snapgen-reference-${index + 1}.${extension}`,
};
} finally {
clearTimeout(timeout);
}
const message =
lastError instanceof Error ? lastError.message : String(lastError || "unknown");
throw new Error(
`SnapGen 参考图下载失败(第 ${index + 1} 张,已重试 ${REFERENCE_FILE_DOWNLOAD_RETRIES} 次):${message}`
);
}
function buildHeaders(apiKey: string) {