25

I am trying to use axios to call an API and return data.

I have the following code which works fine

axios.get('http://api/courses')
  .catch(function (error) {
    if (error.response) {
      console.log(error.response.status);
    } else {
      console.log('Error', error.message);
    }
  })
  .then(response => {
    console.log(response.data)
  });

This works fine, the API returns a 200 and data so in the console I get the data returned.

However this does not work

axios.get('http://api/courses')
  .catch(function (error) {
    if (error.response) {
      console.log(error.response.status);
    } else {
      console.log('Error', error.message);
    }
  })
  .then(response => {
    console.log(response.data)
  });

On the above call i get a 401 returned from the API, I want to be able to detect that and do something (where i am currently doing a console.log). However in the console I get the following errors:

GET http://api/courses 401 (Unauthorized)
(anonymous) @ spread.js:25
e.exports @ spread.js:25
e.exports @ spread.js:25
Promise.then (async)
r.request @ spread.js:25
r.(anonymous function) @ spread.js:25
(anonymous) @ index.js:20
(anonymous) @ (index):49


(index):58 Uncaught (in promise) TypeError: Cannot read property 'data' of undefined
at axios.get.catch.then.response ((index):58)
at <anonymous>

Is there a way to capture a 401? It seems like common practice by API's that require auth, but I cannot seem to work it out. Thanks

davidjh
  • 387
  • 1
  • 7
  • 13
  • Possible duplicate of [How to handle 401 (Authentication Error) in axios and react?](https://stackoverflow.com/questions/47216452/how-to-handle-401-authentication-error-in-axios-and-react) – ADreNaLiNe-DJ Feb 12 '18 at 09:49

4 Answers4

36

You can add an interceptor that will catch all 401 responses. That way you can fire a redirect or any sort of actions you might need. In this example I am dispatching a redux action that will clean up some user data and render the login form.

const UNAUTHORIZED = 401;
axios.interceptors.response.use(
  response => response,
  error => {
    const {status} = error.response;
    if (status === UNAUTHORIZED) {
      dispatch(userSignOut());
    }
    return Promise.reject(error);
 }
);
Bruno Paulino
  • 5,611
  • 1
  • 41
  • 40
  • 3
    When a request gets a `401` response, setting an interceptor on the Axios instance works, but the `error.response` remains undefined. This happens with Axios 0.18 and 0.19. So this method doesn't work. – Neil Jun 10 '19 at 17:46
  • 4
    When a failed request with a `401` status code happens and CORS isn't enabled for that authorization pre-flight request, Axios will not get access to the actual response. This needs to be fixed on the server. The advice presented here for Spring Boot is analogous to any other API: https://www.baeldung.com/spring-security-cors-preflight – Neil Jun 10 '19 at 17:58
  • did you just throw `dispatch` right in middle of the interceptor and expected that it will work?!!!! jc – Pourya Da Nov 21 '19 at 01:44
  • 1
    You are missing the point here. This is just a snippet of code. The dispatch function is available in the context that is left out from the answer for brevity. – Bruno Paulino Nov 21 '19 at 02:35
1

For me (with axios 0.19) both work:

axios.interceptors.response.use(response => response, error => {
    if(error.response.status === 401) store.dispatch(logout);
    return error;
});

and

axios.interceptors.response.use(response => {
    if(response.status === 401) store.dispatch(logout);
    return response;
});

I'm adding this because I've saw both versions in different sources and also Neil told that the version that uses the error handler to intercept didn't work for them, so may be another one is helpful to somebody too.

YakovL
  • 7,557
  • 12
  • 62
  • 102
  • Hi @YakovL, I've updated axios lib with version 0.19.1 but im still getting response: undefined in the interceptor, i need to catch status code 401, is there any solution for it. Please let me konw. – Sagar Ganesh Jan 09 '20 at 07:48
  • @Shree would you mind creating a new question and providing the relevant bits of your code there? – YakovL Jan 09 '20 at 11:12
  • That worked perfectly fine! Thank you very much, but I would like to now more about that. Is the error object in the arrow function the intercepted error coming from javascript? – Taranis Sep 17 '21 at 08:06
  • 1
    @Taranis that's not likely (I guess, that's an enriched object), but it's not that simple to find the exact defintion in the source code (you can try yourself, though); I'd see what is really passed using just console and also read the [docs](https://github.com/axios/axios#handling-errors). – YakovL Sep 20 '21 at 09:24
0

Added debugger to check the object, so this is how the error object looks like.

Refer screenshot. Right side(under scope)

enter image description here

Ashish Singh Rawat
  • 1,419
  • 16
  • 30
0

It very easy to catch and handle 401 through the error.response.

error => {
    if (err.response.status) {
            props.navigation.navigate('Login');
            return;
         }
         });
Code Lover
  • 723
  • 1
  • 10
  • 24