Combining user signal with timeout
Use case
You want both a per-request timeout and the ability to cancel manually. parcely handles this automatically.
Smallest working example
import { createClient } from '@parcely/core'
const http = createClient({ baseURL: 'https://api.example.com' })
const controller = new AbortController()
await http.get('/data', {
signal: controller.signal,
timeout: 5000,
})
// Either:
// - The user calls controller.abort() → ERR_ABORTED
// - 5 seconds elapse → ERR_TIMEOUT
// - The request completes → success
How it works
Internally, parcely uses AbortSignal.any([userSignal, AbortSignal.timeout(ms)]) to combine both signals. Whichever fires first wins:
- User abort:
HttpErrorwithcode: 'ERR_ABORTED' - Timeout:
HttpErrorwithcode: 'ERR_TIMEOUT'
Axios equivalent
In axios, timeout and signal are also independent. The behaviour is similar, but axios uses different error codes (ECONNABORTED for timeout).
Notes and gotchas
AbortSignal.anyis available in Node 20+, all modern browsers, Bun, and Deno.- Timers are always cleaned up in
finally, even when the request succeeds or the user signal fires. - If only
timeoutis set (nosignal), parcely usesAbortSignal.timeout(ms)directly. - If only
signalis set (notimeout), it is passed tofetchas-is.