How to manage axios errors globally or from one point
While just handling errors globally inside the interceptor works in some case, there are times when you'd want more control as to whether the error should be handled globally.
I personally compose errors globally and call the handlers locally. With this approach, i can decide to not handle the error globally in some cases. I can also decide to invoke the global handler only when certain conditions are met.
Below is a simple implementation of a globally composed error handler. To better understand this technique, you may want to check this article (A short story on ajax error handlers).
import axios from 'axios';
import {notifier} from './util';
// errorComposer will compose a handleGlobally function
const errorComposer = (error) => {
return () => {
const statusCode = error.response ? error.response.status : null;
if (statusCode === 404) {
notifier.error('The requested resource does not exist or has been deleted')
}
if (statusCode === 401) {
notifier.error('Please login to access this resource')
}
}
}
axios.interceptors.response.use(undefined, function (error) {
error.handleGlobally = errorComposer(error);
return Promise.reject(error);
})
// Fetch some missing information
axios.get('/api/articles/not-found').then(resp => {
// Do something with article information
}).catch(error => {
const statusCode = error.response ? error.response.status : null;
// We will handle locally
// When it's a 404 error, else handle globally
if (statusCode === 404) {
// Do some specific error handling logic for this request
// For example: show the user a paywall to upgrade their subscription in order to view achieves
} else {
error.handleGlobally && error.handleGlobally();
}
})
// Fetch some missing information
axios.get('/api/users/not-found').then(resp => {
// Do something with user information
}).catch(error => {
// We want to handle globally
error.handleGlobally && error.handleGlobally();
})
You should use an interceptor.
First, create an axios instance using the create
method. This is what you would need to use throughout your app instead of referencing axios
directly. It would look something like this:
let api = axios.create({
baseURL: 'https://example.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
Then attach an interceptor to your axios instance to be called after the response to each of the requests for that instance:
api.interceptors.response.use((response) => response, (error) => {
// whatever you want to do with the error
throw error;
});