Files
orcs-code/src/services/api/fetchWithProxyRetry.ts

45 lines
1.2 KiB
TypeScript

import { disableKeepAlive, getProxyFetchOptions } from '../../utils/proxy.js'
const RETRYABLE_FETCH_ERROR_PATTERN =
/socket connection was closed unexpectedly|ECONNRESET|EPIPE|socket hang up|Connection reset by peer|fetch failed/i
export function isRetryableFetchError(error: unknown): boolean {
if (!(error instanceof Error)) {
return false
}
if (error.name === 'AbortError') {
return false
}
return RETRYABLE_FETCH_ERROR_PATTERN.test(error.message)
}
export async function fetchWithProxyRetry(
input: string | URL | Request,
init?: RequestInit,
options?: { forAnthropicAPI?: boolean; maxAttempts?: number },
): Promise<Response> {
const maxAttempts = Math.max(1, options?.maxAttempts ?? 2)
let lastError: unknown
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fetch(input, {
...init,
...getProxyFetchOptions({
forAnthropicAPI: options?.forAnthropicAPI,
}),
})
} catch (error) {
lastError = error
if (attempt >= maxAttempts || !isRetryableFetchError(error)) {
throw error
}
disableKeepAlive()
}
}
throw lastError instanceof Error
? lastError
: new Error('Fetch failed without an error object')
}