Research sample · Web platform

Fetch timeouts and cancellation

Research question

Is this the most modern way to handle fetch timeouts and cancellation in TypeScript?

Topics covered: Fetch timeout, AbortController, HTTP error handling

Default research

Web platform · 326 characters

Research complete

Question

Is this the most modern way to handle fetch timeouts and cancellation in TypeScript?

Submitted code · fetch-json-timeout.tsTypeScript
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

TypeScript3 priority findings4 displayed sources

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
  1. 01

    AbortController is still the right foundation

    Keep

    Passing an AbortSignal to fetch remains the current web-platform pattern for cooperative cancellation.

    fetch-json-timeout.ts:5

    fetch(url, { signal: controller.signal })
    S1 · S5
  2. 02

    Check the HTTP result before parsing JSON

    Fix next

    Fetch 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()
    S2 · S4
  3. 03

    Give callers a clear cancellation contract

    Decide

    The helper cannot distinguish its own timeout from caller-initiated cancellation. Add the distinction when callers need it.

    fetch-json-timeout.ts:3

    controller.abort()
    S1 · S5

Use the platform timeout signal

Reject non-success responses explicitly and use the runtime timeout signal where supported.

Modernized techniqueTypeScript
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

What this TypeScript Fetch timeout audit covers

This compact helper uses AbortController and a timer to stop a Fetch request. Hattrick examines whether that pattern remains current, what changes when AbortSignal.timeout is available, and which HTTP and cancellation behaviors the helper leaves implicit.

Even a small function benefits from source-backed research when browser and server runtimes evolve. The report keeps the modern cancellation foundation, identifies the missing response-status check, and presents a smaller alternative without pretending every caller needs the same timeout contract.

Engineering questions answered

  • Is AbortController still the modern primitive for cancelling Fetch?
  • Why must a Fetch helper check response.ok before parsing JSON?
  • When should timeout cancellation be distinguished from caller cancellation?

How Hattrick approaches the question

  1. 01

    Focused API research

    Checks the helper against the DOM, Fetch, and HTTP standards instead of relying on remembered patterns.

  2. 02

    Proportional findings

    Preserves the parts that are current and limits recommendations to meaningful failure-contract gaps.

  3. 03

    Adaptable code example

    Shows how AbortSignal.timeout can simplify the helper when the supported runtime provides it.

Practical takeaway

Modern syntax still needs an explicit failure contract

A concise Fetch wrapper should define what counts as success, how timeouts are represented, and whether callers can supply their own cancellation signal. Modern APIs reduce boilerplate, but they do not make those product decisions automatically.