DS
Back to JavaScript

retry-fetch.js

javascript/async/retry-fetch.js
JavaScript

Fetch wrapper with automatic retry, exponential backoff, and timeout.

retry-fetch.js
/**
 * @description Fetch wrapper with automatic retry, exponential backoff, and timeout.
 * @tags fetch, async, retry, network
 */
export async function retryFetch(url, options = {}) {
  const {
    retries = 3,
    delay = 1000,
    backoff = 2,
    timeout = 8000,
    ...fetchOptions
  } = options;

  let attempt = 0;
  let currentDelay = delay;

  while (attempt <= retries) {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), timeout);

    try {
      const response = await fetch(url, {
        ...fetchOptions,
        signal: controller.signal,
      });
      clearTimeout(timer);

      if (!response.ok && attempt < retries) {
        throw new Error(`HTTP error ${response.status}`);
      }

      return response;
    } catch (error) {
      clearTimeout(timer);
      attempt++;
      if (attempt > retries) {
        throw new Error(`Failed after ${retries} retries: ${error.message}`);
      }
      await new Promise((resolve) => setTimeout(resolve, currentDelay));
      currentDelay *= backoff;
    }
  }
}