Skip to content
tezvyn:

Fetch API Errors: Why a 404 is a 'Success'

Source: developer.mozilla.orgEasyHow cards are made

Fetch API Errors: Why a 404 is a 'Success'

A fetch() call only fails on network errors, not on HTTP errors like 404. You must check the response.ok property to see if the request was successful. The footgun is assuming a catch block will handle a 404; it won't.

Why it exists

The Fetch API was designed as a low-level interface for HTTP requests. It intentionally separates network transport failures (like a DNS error or no connection) from application-level HTTP status codes (like 404 or 500). The promise is only rejected for network issues, forcing you to explicitly handle the server's response, whatever it may be.

The mental model

Think of fetch() as confirming a message was delivered, not that the recipient liked the message. The promise resolves successfully if the server receives the request and sends any response back, even a 404 error page. The promise only rejects if the message could not be delivered at all due to a network or connection problem.

How it works

The standard pattern is to wrap your fetch() call in a try...catch block. The fetch() promise resolves with a Response object. This object has a boolean property, response.ok, which is true only for successful HTTP statuses in the 200-299 range. Inside your try block, you must check if (!response.ok). If it's false, you manually throw new Error() with details like response.status. This allows your single catch block to handle both network errors (which cause an automatic rejection) and HTTP status errors (which you throw yourself).

When to use it

Use this try/catch and response.ok check for virtually every fetch call. It is the standard, correct way to handle situations where a server error (like 404 Not Found or 503 Service Unavailable) needs to be handled differently from a successful response.

When not to use it

This pattern is fundamental to using the raw Fetch API. You would only skip this if using a higher-level data-fetching library (like Axios or TanStack Query) that wraps fetch and provides its own, more abstract error handling mechanism.

One canonical example

async function getData() {
const url = "https://example.org/products.json";
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(Response status: ${response.status});
}
const result = await response.json();
console.log(result);
} catch (error) {
console.error(error.message);
}
}

Interview question

Why does a fetch() call with a 404 Not Found status code resolve its promise instead of rejecting it?

  • a.The browser automatically retries requests that result in 4xx status codes before rejecting.
  • b.The server successfully received the request and sent a response, even if it indicates an error.Correct
  • c.A 404 status is not considered a severe enough error to warrant a promise rejection.
  • d.The fetch() API is designed to only reject promises for client-side JavaScript errors.
Why?

The Fetch API's promise resolves if the server successfully receives the request and sends any response back, regardless of the HTTP status code. It only rejects for network-level failures, not application-level HTTP errors like 404. The most tempting distractor (C) is wrong because the reason isn't about the severity of the error, but about the successful delivery of *any* response from the server.

Just read this? Test yourself on what you have been reading.

Read the original → developer.mozilla.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on web apis — each one lists the topics its interview covers.

See open roles