Handling Axios error in React
My suggestion is to use a cutting-edge feature of React. Error Boundaries
This is an example of using this feature by Dan Abramov. In this case, you can wrap your component with this Error Boundary component. What is special for catching the error in axios is that you can use interceptors for catching API errors. Your Error Boundary component might look like
import React, { Component } from 'react';
const errorHandler = (WrappedComponent, axios) => {
return class EH extends Component {
state = {
error: null
};
componentDidMount() {
// Set axios interceptors
this.requestInterceptor = axios.interceptors.request.use(req => {
this.setState({ error: null });
return req;
});
this.responseInterceptor = axios.interceptors.response.use(
res => res,
error => {
alert('Error happened');
this.setState({ error });
}
);
}
componentWillUnmount() {
// Remove handlers, so Garbage Collector will get rid of if WrappedComponent will be removed
axios.interceptors.request.eject(this.requestInterceptor);
axios.interceptors.response.eject(this.responseInterceptor);
}
render() {
let renderSection = this.state.error ? <div>Error</div> : <WrappedComponent {...this.props} />
return renderSection;
}
};
};
export default errorHandler;
Then, you can wrap your root component passing axios instance with it
errorHandler(Checkout, api)
As a result, you don't need to think about error inside your component at all.
The getAllPeople
function already returns the data or error message from your axios
call. So, in componentDidMount
, you need to check the return value of your call to getAllPeople
to decide whether it was an error or valid data that was returned.
componentDidMount() {
getAllPeople().then(response => {
if(response!=error) //error is the error object you can get from the axios call
this.setState(() => ({ people: response}));
else { // your error handling goes here
}
});
}
If you want to return a promise from your api, you should not resolve the promise returned by your axios
call in the api. Instead you can do the following:
export function getAllPeople() {
return axios.get("/api/getAllPeople");
}
Then you can resolve in componentDidMount
.
componentDidMount() {
getAllPeople()
.then(response => {
this.setState(() => ({ people: response.data}));
})
.catch(error => {
// your error handling goes here
}
}
Better way to handle API error with Promise catch method*.
axios.get(people)
.then((response) => {
// Success
})
.catch((error) => {
// Error
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
// console.log(error.response.data);
// console.log(error.response.status);
// console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the
// browser and an instance of
// http.ClientRequest in node.js
console.log(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
console.log(error.config);
});