ai-chatbot/lib/canvas/enhance-task-poll.ts

40 lines
1.5 KiB
TypeScript

// 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<any> {
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("轮询超时");
}