Default research
Web platform · 326 characters
Question
Is this the most modern way to handle fetch timeouts and cancellation in TypeScript?
export async function fetchJson(url: string, timeoutMs = 5000) {
const controller = new AbortController()
const timer = setTimeout(() => controller.abort(), timeoutMs)
try {
const response = await fetch(url, { signal: controller.signal })
return await response.json()
} finally {
clearTimeout(timer)
}
}Result
Modern foundation, incomplete failure contract
The cancellation primitive is current, but the helper leaves important failure behavior implicit. Keep AbortController, then make HTTP errors and timeout semantics explicit.
Priority findings
03- 01S1 · S5
AbortController is still the right foundation
KeepPassing an AbortSignal to fetch remains the current web-platform pattern for cooperative cancellation.
fetch-json-timeout.ts:5
fetch(url, { signal: controller.signal }) - 02S2 · S4
Check the HTTP result before parsing JSON
Fix nextFetch resolves for HTTP error statuses. Check response.ok or response.status before treating the body as successful.
fetch-json-timeout.ts:6
return await response.json() - 03S1 · S5
Give callers a clear cancellation contract
DecideThe helper cannot distinguish its own timeout from caller-initiated cancellation. Add the distinction when callers need it.
fetch-json-timeout.ts:3
controller.abort()
Use the platform timeout signal
Reject non-success responses explicitly and use the runtime timeout signal where supported.
export async function fetchJson(url: string, timeoutMs = 5000) {
const response = await fetch(url, {
signal: AbortSignal.timeout(timeoutMs),
})
if (!response.ok) throw new Error(`HTTP ${response.status}`)
return response.json()
}Authoritative sources

