Thought leadership from the most innovative tech companies, all in one place.

How to Handle Unsuccessful Fetch API Calls in JavaScript

So, in the previous post, we saw all possible things (except error handling) with fetch(url, {options}). If you haven't read it yet, give it a read here.

Today, we will be learning about how to handle the errors or any unsuccessful calls made by the fetch(). We will be using the same URL as in the previous post. Without any further ado let's get right into it!

In the previous post, I mentioned a point:

Fetch always succeeds or gets a response unless there's some sort of network error.

Well, it also fails if the syntax is wrong or the URL is invalid, which are obvious cases. Remember these as point 1. Now, Let's see the syntax for the catch() :

fetch("<https://reqres.in/api/users/1>")
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.log(error));

It comes after all the .then() and is used to handle the rejected promises.
Remember this as point 2 → "It handles the promises that are rejected"

First, let us see what happens when we access the details of a user who does not exist. As far as we know, we should get back a '404' error saying not found, right?

fetch("<https://reqres.in/api/users/34>")
  .then((res) => res.json())
  .then((data) => console.log(data));

image

We neither see an error, nor any data but the promise is fulfilled. so you might think that having a catch() block at the end would work, but :

fetch("<https://reqres.in/api/users/34>")
  .then((res) => res.json())
  .then((data) => console.log(data))
  .catch((error) => console.log(error));

image

See? No change. How can the catch handle the error if no error is thrown?
Now, think about the first point I wanted you to remember. According to that, 404 error is not an error for the fetch(), so it succeeds in returning a promise. Returning a promise in the sense, the promise is not rejected. According to the second point to be remembered, the catch() block handles the rejection of a promise, and hence it does not handle this error, because a promise is returned here. In the above image, you can see the promise state as 'fulfilled'.

To handle such errors, fetch provides an "ok" property for the response object it returns. We can print the res object to see these details :

fetch(
  "[https://reqres.in/api/users/34](https://reqres.in/api/users/3432)"
).then((res) => console.log(res));

image

Before returning the response object, we can just check if the 'ok' is set to true or false. It represents the status code of the fetch call. If the status code is of form 2xx, 'ok' will be set to true, else it will be set to false (for 4xx and 5xx status codes).

fetch("<https://reqres.in/api/users/34>")
  .then((res) => {
    if (res.ok) return res.json();
    else throw new Error("Status code error :" + res.status);
  })
  .then((data) => console.log(data))
  .catch((err) => console.log(err));

image

The promise state is "fulfilled" but we handled the error now.
Now we can see the proof that the promise is rejected and hence handled by the catch() block. To see the promise state as rejected, remove the catch() block. Also, the data printing block, cause there's no use of this if nothing is returned from the response block, right? (not removing the data block will give the same results)

fetch("<https://reqres.in/api/users/34>").then((res) => {
  if (res.ok) return res.json();
  else throw new Error("Status code error :" + res.status);
});

image

As you can see, the state of promise is rejected and hence a catch block can handle this error. You can print the response instead of returning it, but you'll get the same results.

catch() block can handle syntax errors because if the syntax is wrong :
fetch cannot succeed → so promise not returned→ so error goes to catch
Here, the syntax is wrong, so catch takes the error and prints it :

fetch("[https://reqres.in/api/users/34](https://reqres.in/api/users/3432)")
  .then((res) => resjson())
  .catch((error) => console.log(error));

image

Similarly, Network errors: no network → fetch cannot succeed → so promise not returned→ so error goes to catch

fetch("<https://reqres.in/api/users/4>")
  .then((res) => res.json())
  .catch((err) => console.log(err));

image

But invalid URL directly throws an error "Invalid or unexpected token", because fetch cannot even start the process if the URL is wrong, let alone returning a promise:

fetch("https://reqres.in/api/users/34\")
.then(res=>res.json())
.then(data=>console.log(data))
.catch(error=>console.log(error))

image

Finally, you made it to the end. That's all you need to know about handling unsuccessful calls of fetch().

Hope you enjoyed the article. If you did, consider providing feedback or suggestions in the comment section. Make sure to follow to not miss any of my future posts. Look forward to more interesting articles ahead.




Continue Learning