Catching a fetch error

11,833

Solution 1

APIwithoutcatch is an async function - it doesn't throw an exception but rather will reject the promise that it returns. You need to wait for the promise, either with then or await syntax (just like you did await the fetch within APIwithcatch):

async function API() {
  return fetch("http://wwww.example.com/user.json");
}

function callAPI() {
  try {
    await API();
  } catch (e) {
    console.log(e);
  }
}
callAPI();

Solution 2

Per MDN, the fetch() API only rejects a promise when a “network error is encountered, although this usually means permissions issues or similar.” Basically fetch() will only reject a promise if the user is offline, or some unlikely networking error occurs, such a DNS lookup failure.

However fetch provides a ok flag that we can use to check if the HTTP status code is a success or not and throw a user-defined exception

await response.json() will extract the JSON body content from the response so we can throw it to the .catch block.

    async function APIwithcatch() {
      try {
        var response = await fetch("http://wwww.dfdfdf.com/user.json");

        if (!response.ok) throw await response.json();

        return response;

      } catch (e) {
        console.log(e);
      }
    }

Solution 3

UPD: got your problem, unfortunately you can't catch an error like in your code

Fetch is asynchronous, so you mustn't use try {} catch {} construction, use .then().catch() instead:

async function APIwithoutcatch() {
  var response = await fetch("http://wwww.dfdfdf.com/user.json");
  return response;
}

function callCallAPI() {
  return APIwithoutcatch()
    .then((data) => {
      console.log(data)
    })
    .catch((e) => {
      console.log(e)
    })
}

callCallAPI();
Share:
11,833
DrEarnest
Author by

DrEarnest

Javascript Developer.

Updated on June 04, 2022

Comments

  • DrEarnest
    DrEarnest almost 2 years

    My understanding is that a piece of code throwing error anywhere in callstack can be caught at final catch block. for fetch error, when no internet is available, when I make APIwithoutCatch in callCallAPI, error is not caught. while APIwithCatch catches its own error. All other errors e.g. 404, are caught at both places, wherever I want.

    async function APIwithcatch() {
      try {
        var response = await fetch("http://wwww.dfdfdf.com/user.json");
        return response;
      } catch (e) {
        console.log(e);
      }
    }
    
    async function APIwithoutcatch() {
      var response = await fetch("http://wwww.dfdfdf.com/user.json");
      return response;
    }
    
    function callCallAPI() {
      try {
        // return APIwithcatch();
        return APIwithoutcatch();
      } catch (e) {
        console.log(e);
      }
    }
    callCallAPI();
    My assumption that any error should flow down callstack is correct or not? What is special about net::ERR_INTERNET_DISCONNECTED error?

  • DrEarnest
    DrEarnest over 5 years
    the problem is only with net::ERR_INTERNET_DISCONNECTED error. When there is no connectivity, promise is able to generate an error but try/catch block isn't. I am just trying to understand what is happening?
  • Igor
    Igor over 5 years
    I got your problem so I updated the answer. You may use axios instead of fetch btw, it will solve your problem.
  • DrEarnest
    DrEarnest over 5 years
    I understand the solution. I know it. I just want to know why does try/catch with async/await doesn't work in this condition.
  • DrEarnest
    DrEarnest over 5 years
    It might be because of difference between error and exception or something related to how Promise.reject works. I just want to know that.
  • Igor
    Igor over 5 years
    It didn't work because try body in callCallApi() returns Promise. You may also make callCallApi() asynchronous and do something like try { var res = await APIwithoutcatch(); return res; }