Configure automatic retries for failed requests.
type RetryPolicy = {
attempts?: number | ((ctx: { request: Request }) => number | Promise<number>)
delay?: number | ((ctx: { request: Request; response?: Response; error?: Error; attempt: number }) => number | Promise<number>)
when?: (ctx: { request: Request; response?: Response; error?: Error }) => boolean | Promise<boolean>
}const result = await api.users.get({
params: { id: '123' },
retry: {
attempts: 3,
delay: 1000, // 1 second
},
})By default, retries on non-OK responses. Customize with when:
const result = await api.users.get({
params: { id: '123' },
retry: {
attempts: 3,
delay: 1000,
when: ({ response, error }) => {
// Retry on server errors or network failures
if (error) return true
if (response && response.status >= 500) return true
return false
},
},
})const result = await api.users.get({
params: { id: '123' },
retry: {
attempts: 5,
delay: 2000,
when: ({ response }) => {
if (!response) return false
return response.status === 503 // Service Unavailable
},
},
})Use a delay function for exponential backoff:
const result = await api.users.get({
params: { id: '123' },
retry: {
attempts: 5,
delay: ({ attempt }) => Math.min(1000 * Math.pow(2, attempt), 30000),
when: ({ error }) => !!error,
},
})const endpoint = new Endpoint({
method: 'GET',
pathname: '/users',
retry: {
attempts: 3,
delay: 1000,
when: ({ request }) => request.method === 'GET',
},
})Determine max attempts dynamically:
const result = await api.users.get({
params: { id: '123' },
retry: {
attempts: ({ request }) => {
// Check custom header or metadata
const priority = request.headers.get('X-Priority')
return priority === 'high' ? 5 : 2
},
delay: 1000,
},
})The when and delay functions receive context about the request:
retry: {
when: ({ request, response, error }) => {
// request: The Request object
// response: The Response if received, undefined if network error
// error: NetworkError, TimeoutError, etc. if occurred
return true
},
delay: ({ request, response, error, attempt }) => {
// attempt: Current attempt number (1-indexed)
return attempt * 1000
},
}Without a when condition, retries on non-OK responses:
retry: {
attempts: 3,
delay: 0,
// when: defaults to ({ response }) => response?.ok === false
}Set default retry on the endpoint:
const endpoint = new Endpoint({
method: 'GET',
pathname: '/users',
retry: {
attempts: 3,
delay: 1000,
},
})Per-request retry overrides endpoint defaults.
Retries respect AbortSignal:
const controller = new AbortController()
const result = await api.users.get({
params: { id: '123' },
signal: controller.signal,
retry: { attempts: 10, delay: 1000 },
})
// Call controller.abort() to cancel retriesconst api = http_client({
base_url: 'https://api.example.com',
endpoints: {
users: new Endpoint({
method: 'GET',
pathname: '/users',
retry: {
attempts: 3,
delay: ({ attempt }) => Math.min(100 * Math.pow(2, attempt), 5000),
when: ({ response, error }) => {
if (error) return true
if (!response) return false
return response.status >= 500 || response.status === 429
},
},
}),
},
})