Qwertie
Qwertie

Reputation: 6493

Catching axios request errors application wide

In my SPA I am using axios to make requests to the API. I currently use axios request interceptors to add auth headers to requests but I also wanted to use them to catch 401 errors and remove the locally stored auth token.

I attempted to add this to the current interceptor

   axios.interceptors.response.use((response) => {
        // Set user headers only if they are not blank.
        // If DTA gets a lot of request quickly, it won't return headers for some requests
        // so you need a way to keep headers in localStorage to getting set to undefined
        if (response.headers['access-token']) {
            localStorage.setItem('access-token', response.headers['access-token'])
            localStorage.setItem('client', response.headers.client)
            localStorage.setItem('uid', response.headers.uid)
            localStorage.setItem('token-type', response.headers['token-type'])
        }

        if (response.status === 401) {
            localStorage.setItem('access-token', '')
            localStorage.setItem('client', '')
            localStorage.setItem('uid', '')
            localStorage.setItem('token-type', '')
        }
        // You have to return the response here or you won't have access to it
        // later
        return response
    })

But I found out the interceptors don't seem to run when the status returns an error code. Is there any way I can catch these errors application wide without having to add this error handling to every request manually?

Upvotes: 1

Views: 2055

Answers (3)

Dinesh Pandiyan
Dinesh Pandiyan

Reputation: 6289

To handle the errors from a response, you need to use the second parameter of the callback in response interceptor.

axios.interceptors.response.use((response) => {
  // Set user headers only if they are not blank.
  // If DTA gets a lot of request quickly, it won't return headers for some requests
  // so you need a way to keep headers in localStorage to getting set to undefined
  if (response.headers['access-token']) {
    localStorage.setItem('access-token', response.headers['access-token']);
    localStorage.setItem('client', response.headers.client);
    localStorage.setItem('uid', response.headers.uid);
    localStorage.setItem('token-type', response.headers['token-type']);
  }

  // You have to return the response here or you won't have access to it
  // later
  return response;
}, (error) => {
  // do what you want to do when error happens
  if (error.response.status === 401) {
    localStorage.setItem('access-token', '');
    localStorage.setItem('client', '');
    localStorage.setItem('uid', '');
    localStorage.setItem('token-type', '');
  }

  else if(error.response.status === 500) {
    // do something for all 500 errors
  } else {
    // do something for all other error codes
  }

  // should reject the promise so your api call goes to catch block
  return Promise.reject(error);
});

Refer official axios docs for more info

I have an axios interceptor library published in npm. You can refer to the source code for more details on error handling in interceptors.

axios-retry-intercceptor

Upvotes: 4

alegria
alegria

Reputation: 1145

You can define and export an error handler function that accepts an error parameter in one of your helper, util etc. classes, then you can call this method with one line inside every catch block.

Or,

You define a doRequest() method that handles the sending and response handling of the process altogether, and feed that method with your custom request-related parameters, like a JSON object of { url: 'A', method: X, data : Y}, call this helper method from everywhere.

Upvotes: 0

Łukasz Blaszyński
Łukasz Blaszyński

Reputation: 1565

Add second function to interceptor 'errorresponseHandler':

function errorResponseHandler(error) {

}

// apply interceptor on response
axios.interceptors.response.use(
    response => response,
    errorResponseHandler
);

Upvotes: 0

Related Questions