5

I am using React with axios and redux-promise. Axios does not appear to catch the 404 error, as below.

axios writes the 404 error to the console, even when I am handling it

This is the code.

 const url = FIVE_DAY_FORECAST_URL.replace("{0}", city);

  axios.interceptors.response.use(function (response) {
    return response;
  }, function (error) {
     return Promise.reject(error);
  });

  try{
    const request = axios.get(`${url}`).then(e => { 
       debugger; }).catch(
      e => {
        debugger;
        return "ERROR"; // THIS FIRES, BUT DOES NOT STOP THE CONSOLE ERROR
      });
      debugger;
    return {
      type: FETCH_FIVE_DAY_FORECAST,
      payload: request
    };
  } catch {
    debugger;
    console.log("Error!");  // DOES NOT HELP AS THE 404 IS NOT A JAVASCRIPT ERROR, IT'S A VALID SERVER RESPONSE
  }
}

I am using a number of techniques to tr to catch the console error:

  • .then() ==> the code runs through this block, but the error has already happened, and has been written to the console!

  • .catch() ==> the code runs through this block if the interceptors are not configured i.e. comment out axios.interceptors.response.use... .

  • try...catch ==> no effect (does not catch the network response as this is not really a javascript error!)

Banoona
  • 1,470
  • 3
  • 18
  • 32
  • 2
    it just shows a message on the debug console, but it isn't a arror, and will not interrupt your code execution. your code seems to work as intended, and that log message is really a problem? – Murilo Cruz Mar 16 '19 at 04:43
  • Agreed, it "works" but the environment is polluted with red, where this is not really an application error condition. As this app grows, I would not want it flagging up noise where there isn't any error. – Banoona Mar 17 '19 at 17:20
  • @Banoona Then don't try to fetch resources that don't exist, or don't send 404 errors when you mean a different thing. You can hide the messages in the console, btw. – Bergi Mar 17 '19 at 19:51
  • 1
    Thanks @Bergi. Not really the answer to the problem though. Yes, I could limit the options (e.g. by dropdown list). But that's not the point. The javascript interface should be able to catch 404 errors gracefully. "Not found" is a valid response, so I should be able to catch it and display to the user "Location not found" (without any noise in the console log) Also, it's not my API so I can't control the status codes returned. – Banoona Mar 18 '19 at 20:07
  • 1
    @Banoona Your javascript can and does catch the 404 error, you can gracefully handle it however you like (displaying messages to the user). That has nothing to do with the console being helpful. The user does not care about the console log. – Bergi Mar 18 '19 at 20:12
  • @Bergi, OK. Yes, but from an application point of view, where an application can grow and it needs long term maintainability, it is in my view better not to pollute the console with noise, and I would consider this a bug in the axios implementation if it is not able to catch http errors. I believe at least some devs agree on this point e.g. https://github.com/axios/axios/issues/960 (please read wonderbeyond) – Banoona Mar 18 '19 at 20:18
  • @Bergi - could you please provide a link to the duplicate question, as I don't find it here on this one. Many Thanks! – Banoona Mar 18 '19 at 20:19
  • @Banoona You can find the link in the box at the top of the question – Bergi Mar 18 '19 at 20:20
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/190265/discussion-between-banoona-and-bergi). – Banoona Mar 18 '19 at 20:21

2 Answers2

3

When using try...catch with axios you explicitly have to state the error response like so

catch(error) {
  console.log('[error]', error.response);
  // use the error.response object for some logic here if you'd like
}

Otherwise it just returns the string value.

With that response object you can then utilize some logic to do something based on the particular error. More info can be found here https://github.com/axios/axios/issues/960

I hope this helps.

Mark
  • 1,610
  • 1
  • 14
  • 27
  • 4
    Hi Mark. Thanks, but not sure that this really solves the issue. The issue is that the catch statement does not suppress the red error message logged into the console (which happens before it goes into the catch block, and so is out of my control) – Banoona Mar 16 '19 at 05:33
0

You are trying to catch the Promise.reject and wrapping it in a try...catch. Only one of this will work.

You can either catch a promise rejection or wrap the promise in a try...catch and throw a new error on promise rejection and catch it in catch block.

Try this code

const url = FIVE_DAY_FORECAST_URL.replace("{0}", city);

axios.interceptors.response.use(function (response) {
  return response;
}, function (error) {
   return Promise.reject(error);
});

try {
  const request = axios.get(`${url}`)
  .then(
    response => {
      debugger;
    })
    .catch(
    e => {
      debugger;
      throw e // throw the error and catch it
    });
    debugger;
  return {
    type: FETCH_FIVE_DAY_FORECAST,
    payload: request
  };
} catch {
  debugger;
  // Now you can catch the error in catch block
  console.log("Error!");
}

// or you can't write async/await code
// make the the function is marked as `async`

try {
  const response = await axios.get(`${url}`)
  return {
    type: FETCH_FIVE_DAY_FORECAST,
    payload: response
  };
} catch (e) {
  console.error("Error happened during fetch");
  console.error(e);
}
Dinesh Pandiyan
  • 5,814
  • 2
  • 30
  • 49
  • the async one doesn't work: the console still logs the 404, and we get: redux.js:192 Uncaught (in promise) Error: Actions must be plain objects. Use custom middleware for async actions. at dispatch (redux.js:192) at index.js:57 at dispatch (redux.js:613) – Banoona Mar 17 '19 at 17:19
  • your first one doesn't catch the error either. Chrome logs it as a network error, before it is trapped by the javascript code. – Banoona Mar 17 '19 at 17:30