Fetch JSON With Retry and Timeout

Fetch JSON from an endpoint, applying a per-attempt timeout and retrying transient failures while treating client errors as final.

JavascriptData Fetching

Code

snippet
export async function fetchJson(url, options = {}) {
  const attempts = options.attempts ?? 3;
  const timeoutMs = options.timeoutMs ?? 5000;
  let lastError;
  for (let attempt = 1; attempt <= attempts; attempt++) {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), timeoutMs);
    try {
      const response = await fetch(url, { signal: controller.signal });
      if (response.status >= 500) throw new Error("server error " + response.status);
      if (!response.ok) return { ok: false, status: response.status, data: null };
      return { ok: true, status: response.status, data: await response.json() };
    } catch (error) {
      lastError = error;
    } finally {
      clearTimeout(timer);
    }
  }
  throw lastError;
}