Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to handle fetch errors

Short answer

There are two kinds of errors: the network fails and fetch() throws, or the server answers with an error status. Handle both:

try {
  const response = await fetch('/api/profile');
  if (!response.ok) {
    throw new Error(`Server error: ${response.status}`);
  }
  const profile = await response.json();
  showProfile(profile);
} catch (error) {
  showMessage('Could not load the profile: ' + error.message);
}

A helper function

Put the checks in one function and use it everywhere:

async function getJson(url, options) {
  const response = await fetch(url, options);
  if (!response.ok) {
    const text = await response.text();
    throw new Error(`${response.status} ${response.statusText}: ${text.slice(0, 100)}`);
  }
  return response.json();
}
 
const orders = await getJson('/api/orders');

Different statuses

Sometimes the reaction depends on the status: 401 means you need to log in, 404 means nothing was found:

const response = await fetch('/api/orders/15');
 
if (response.status === 401) {
  location.href = '/login';
} else if (response.status === 404) {
  showMessage('Order not found');
} else if (response.ok) {
  showOrder(await response.json());
}

Common mistake

Without await inside try, the error happens later, outside the block, and catch does not catch it:

try {
  fetch('/api/profile').then((response) => response.json());
} catch (error) {
  // never runs for request errors
}

Functions used in this recipe

  • fetch — Sends an HTTP request and returns a promise of the response.
  • try...catch — Catches errors so the program does not stop.

Thanks for reading!

Donate to the site — we work hard for you.