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.