Stop Fetch-ing in error

Intro

Before we jump in. If you are thinking I use axios or requestjs etc so this doesn't apply to me. Put the npm package down and step away from the install!

Fetch is now supported in all major browsers and even in NodeJS now!

Which is awesome! We now have a single way of making requests across the browser and backend! So much time and npm downloads saved!

Also if you need to support really old browsers, there is an official polyfill you can load on your website to provide you with the same fetch experience.

Now let’s jump in!

The Problem

Fetch is awesome a really great way of making requests from your code.

However I've seen in many tutorials and code the following code, which will cause issues:

    fetch('http://example.com/movies.json')
    .then((response) => response.json())
    .then((data) => console.log(data));

Even in the Mozilla docs

Why is this a problem?

If the endpoint you are fetching, returns a not okay status code then fetch will not throw an error. You have to check yourself if the status code if okay or not before trying to get the response body with response.json(). Otherwise you could end up with some generic error and no context around what caused it.

But, you might be saying to yourself well my endpoint always returns JSON, even in an error scenario. This may be the case, but if anything out of your control errors for example an API Gateway then you are very likely to get a non JSON response and again cause yourself a headache debugging.

The Solution

The solution to this is really straightforward, simply check if the response if ok, before attempting to get the response body.

You can see in this example, I'm checking response.ok which indicates if your response status was in the 2XX range.

But you can also check for specific statuses as well. Here I'm checking for a 204 - No Content status code as I won't have any JSON to return in this instance.

Otherwise I reject the promise, returning the full response in the error.

I've also wrapped it in a try catch for safety in order to catch any CORS, timeout errors etc.

    const request = new Request('http://example.com/movies.json');
    try {
      const response = await fetch(request);
      if (response.ok && response.status !== 204) {
        return response.json();
      }
      if (response.ok && response.status === 204) {
        return Promise.resolve();
      }
      return Promise.reject(response);
    } catch (e) {
      return Promise.reject(e);
    }

Summary

In summary, fetch is awesome!

However there is a bit more to it in order to handle errors and bad responses from any endpoint you might be hitting, so double check your fetch code to make sure you are handling errors gracefully. It will definitely help when it comes to debugging any problems.

Happy Building!

These are webmentions powered by webmention.io