Q69: provider failures classify by status and code; cooldowns follow Retry-After or back off

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-08 12:03:37 -04:00
1 parent 4325dfa874
commit c6a0460035
15 files changed
+198 -41

No files matched your search

+7 -4
View File
@@ -34,6 +34,9 @@ export class ProviderHttpError extends Error {
constructor(
message: string,
readonly rateLimitState: ProviderObservedRateLimitState | null,
/** HTTP status of the failed response; null when no response arrived. */
readonly status: number | null = null,
readonly timedOut = false,
) {
super(message);
this.name = "ProviderHttpError";
@@ -86,7 +89,7 @@ export async function postEventStream(
const raw = await withDeadline(controller, timeouts.bodyTimeoutMs ?? BODY_TIMEOUT_MS, () => response.text());
const data = parseProviderJson(raw, false);
const message = readProviderError(data) ?? (raw.trim() || `Provider request failed with HTTP ${response.status}.`);
throw new ProviderHttpError(message, rateLimitState);
throw new ProviderHttpError(message, rateLimitState, response.status);
}
if (!response.body) throw new ProviderHttpError("Provider returned an empty event stream.", rateLimitState);
return { messages: readServerSentEvents(response.body, timeouts.idleTimeoutMs ?? STREAM_IDLE_TIMEOUT_MS), rateLimitState };
@@ -100,7 +103,7 @@ async function requestJson(endpoint: string, init: RequestInit, timeouts: Provid
const data = parseProviderJson(raw, response.ok);
if (!response.ok) {
const message = readProviderError(data) ?? (raw.trim() || `Provider request failed with HTTP ${response.status}.`);
throw new ProviderHttpError(message, rateLimitState);
throw new ProviderHttpError(message, rateLimitState, response.status);
}
return { data, rateLimitState };
}
@@ -126,7 +129,7 @@ async function withDeadline<T>(controller: AbortController, timeoutMs: number, o
return await operation();
} catch (error) {
throwIfRunStopped();
if (controller.signal.aborted) throw new ProviderHttpError("Provider request timed out.", null);
if (controller.signal.aborted) throw new ProviderHttpError("Provider request timed out.", null, null, true);
throw error;
} finally {
clearTimeout(timer);
@@ -175,7 +178,7 @@ async function readWithIdleDeadline(
): Promise<ReadableStreamReadResult<Uint8Array>> {
let timer: NodeJS.Timeout | undefined;
const idle = new Promise<never>((_, reject) => {
timer = setTimeout(() => reject(new ProviderHttpError("Provider stream timed out.", null)), idleTimeoutMs);
timer = setTimeout(() => reject(new ProviderHttpError("Provider stream timed out.", null, null, true)), idleTimeoutMs);
});
try {
return await Promise.race([reader.read(), idle]);