fix retry Codex and OpenAI fetches via proxy-aware helper (#720)
This commit is contained in:
44
src/services/api/fetchWithProxyRetry.ts
Normal file
44
src/services/api/fetchWithProxyRetry.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
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')
|
||||
}
|
||||
Reference in New Issue
Block a user