What is fetch?

The fetch API is an awesome new addition to the web. As the name suggests it makes fetching things a lot easier. It is based on Promises which therefore support then and catch.

However many developers are a bit confused about the behaviour of fetch on http error codes.

fetch('https://httpstat.us/404')
  .then(() => console.log('success')) // <--
  .catch(() => console.log('failure'));

On first look you might think that this code logs failure to the console, but as soon as you try it, you'll see that it doesn't instead logs success.

Why doesn't it reject on http error codes?

...

How can we make it reject on http error codes?

The solution is quite simple! The Response object returned by fetch contains a Response.ok property which according to MDN:

[states] whether the response was successful (status in the range 200-299) or not.

We can make use of this really neat boolean and write a simple response handler that sits between fetch and your first actual then:

const handler = response => {
  if (!response.ok) throw new Error(response.status);
  return response;
};

// prevent an infinite recursion
const clone = fetch;

// overwrite global fetch to always use the handler
fetch = (...args) => clone.apply(null, args).then(handler);

Our handler is a simple function which takes a Response object as first parameter, checks if ok is false and if so, throws an Error containing the http error code.

If we now try to use our improved fetch you'll see that our initial code returns "failure" as expected.

fetch('https://httpstat.us/404')
  .then(() => console.log('success'))
  .catch(() => console.log('failure')); // <--

Keep in mind that this overwrote fetch globally which could break other libraries. If you just want to use the handler with specific calls, do the following:

fetch('https://httpstat.us/404')
  .then(handler) // <-- handler
  .then(() => console.log('success')) // <-- actual then()
  .catch(() => console.log('failure'));

If you'd like to use this in a project of yours, I created an npm package for it.