// Polling is bounded by elapsed time, including network waits. Terminal provider failures // must escape immediately instead of being converted into a perpetual pending response. export class EnhanceTerminalError extends Error {} export async function pollTaskResult( apiUrl: string, apiKey: string, taskId: string, delay = 1000, timeout = 120000, fetcher: typeof fetch = fetch, ): Promise { const deadline = Date.now() + timeout; while (Date.now() < deadline) { try { const response = await fetcher( `${apiUrl}/api/tasks/visual/scale/${encodeURIComponent(taskId)}`, { method: "GET", headers: { "X-API-KEY": apiKey }, signal: AbortSignal.timeout(Math.max(1, Math.min(10000, deadline - Date.now()))), }, ); if (!response.ok) throw Error(`轮询请求失败: ${response.status}`); const result = await response.json(); if (!result.data) throw Error("高清查询未返回任务状态"); if (result.data.state < 0) throw new EnhanceTerminalError( `AOS任务失败: ${String(result.data.err_message || result.data.err_info || result.data.state_detail || result.data.state)}`, ); if (result.data.progress >= 100) return result; } catch (error) { if (error instanceof EnhanceTerminalError) throw error; } const remaining = deadline - Date.now(); if (remaining > 0) await new Promise((resolve) => setTimeout(resolve, Math.min(delay, remaining))); } throw Error("轮询超时"); }