Skip to content

How to Fix Fetch API Timeout in JavaScript

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about How to Fix Fetch API Timeout in JavaScript. We cover key concepts, practical examples, and best practices.

The Problem

The Fetch API does not have a built-in timeout mechanism. A request can hang indefinitely, leaving the user waiting for a response that never comes.

Quick Fix

Step 1: Use AbortController with setTimeout

Create an abort controller and set a timeout:

const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
fetch('https://api.example.com/data', { signal: controller.signal })
    .then(res => res.json())
    .catch(err => console.log(err.message));
The operation was aborted

If the request takes longer than 5 seconds, it is aborted and the catch block runs.

Step 2: Use AbortSignal.timeout() (modern browsers)

In modern browsers (Chrome 103+, Firefox 100+, Safari 15.4+):

fetch('https://api.example.com/data', { signal: AbortSignal.timeout(5000) })
    .then(res => res.json())
    .catch(err => {
        if (err.name === 'TimeoutError') {
            console.log('Request timed out');
        } else {
            console.log('Request failed:', err.message);
        }
    });

Step 3: Create a reusable timeout wrapper

Build a helper function:

async function fetchWithTimeout(url, options = {}, timeout = 5000) {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), timeout);
    try {
        const response = await fetch(url, {
            ...options,
            signal: controller.signal
        });
        return response;
    } finally {
        clearTimeout(timer);
    }
}
fetchWithTimeout('https://api.example.com/data')
    .then(res => res.json())
    .catch(err => console.log('Timed out:', err.message));

Step 4: Handle timeout vs network error separately

Distinguish between timeout and other errors:

async function fetchWithTimeout(url, timeout = 5000) {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), timeout);
    try {
        const response = await fetch(url, { signal: controller.signal });
        return response;
    } catch (err) {
        if (err.name === 'AbortError') {
            throw new Error(`Request timed out after ${timeout}ms`);
        }
        throw err;
    } finally {
        clearTimeout(timer);
    }
}

Prevention

  • Always set a timeout for fetch requests, especially for user-facing features.
  • Use AbortSignal.timeout() for cleaner code in modern browsers.
  • Show a user-friendly message when a request times out.
  • Implement retry logic with exponential backoff for critical requests.

Common Mistakes with fetch timeout

  1. Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
  2. Using head and tail instead of pattern matching, causing runtime errors on empty lists
  3. Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks

These mistakes appear frequently in real-world JS code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### Can I set a timeout in the fetch init object directly?

No, the Fetch API does not have a timeout option in its init object. You must implement timeout using AbortController or AbortSignal.timeout(). Axios and other HTTP libraries include built-in timeout support, but vanilla fetch does not.

What happens to the network request when I abort it?

Aborting a fetch stops the browser from processing the response, but the server may still receive and process the request. The TCP connection is closed, but the server-side operation continues unless you cancel it separately. For critical operations, use idempotency keys to handle duplicate requests.

Is AbortSignal.timeout() supported everywhere?

AbortSignal.timeout() is supported in Chrome 103+, Firefox 100+, Safari 15.4+, and Node.js 19+. For older environments, use the AbortController + setTimeout pattern described in Step 1. You can also polyfill AbortSignal.timeout() using AbortController internally.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro