Introduction
We are creating a small app for fetch data using React in typescript to show the standard way of writing asynchronous logic for fetching data and adding the Axios Interceptors as well for global error handling. I am giving you the general idea of Error handling so you can use it in any framework you want.
Prerequisite
- Understanding of React, Typescript, and Axios.
- Your server must return status codes if you wanna use this method.
Let's start creating
Create a State
which you can use to determine the status of your request. Here I am using it as enum of "idle" | "pending" | "fulfilled" | "error"
. To know why I did this you need to read this blog .
function App() {
const [status, setStatus] = useState<
"idle" | "pending" | "fulfilled" | "error"
>("idle");
if (status === "idle" || status === "pending") return <Loader />;
if (status === "error") return <h1>Error</h1>;
if (status === "fulfilled") return <h1>Data</h1>;
}
Writing the logic to call the getData
function in useEffect
in a manner that will update the status of the component corresponding to the request status. Here is API Contract looks like this type Data = { data: string }
.
useEffect(() => {
if (status === "idle") {
(async () => {
setStatus("pending");
const res = await getData();
if ("data" in res) {
setStatus("fulfilled");
setData(res.data);
} else {
setStatus("error");
}
})();
}
}, [data, status]);
Creating a getData
function, here getData returned a promise which would resolve as successful response or err response. Responses that have a status code less than 300 are treated as a successful response and responses that have a status code equal to or greater than 300 are treated as error responses by Axios automatically.my API bad response look like type ServerError = { error: string; };
.
const getData = async (): Promise<Data | ServerError> => {
try {
const res = await axios.get<Data>(
"blog-server.gagandeogan.repl.co"
);
return res.data;
} catch (err) {
if (axios.isAxiosError(err)) {
const serverError = err as AxiosError<ServerError>;
if (serverError && serverError.response) {
return serverError.response.data;
}
}
return { error: "something went wrong!" };
}
};
Creating an Interceptor
component for global error handling. Interceptors are middleware in Axios which are quite useful in Error handling. here It is used for logout users if the server returns an unauthenticated status code.
const Interceptor = () => {
const [errorInterceptor, setErrorInterceptor] = useState<number | null>(
null
);
const addErrorInterceptor = () => {
const errorInterceptor = axios.interceptors.response.use(
(res) => {
//use this accordingly..
},
(error) => {
if (error.response) {
const status = error.response.status;
if (status === 403) {
// Logout user
}
}
return Promise.reject(error);
}
);
setErrorInterceptor(errorInterceptor);
};
const removeErrorInterceptor = () => {
if (errorInterceptor) {
axios.interceptors.request.eject(errorInterceptor);
setErrorInterceptor(undefined);
}
};
useEffect(() => {
addErrorInterceptor();
return () => {
removeErrorInterceptor();
};
}, []);
return <></>;
}
By bringing together you have this App
Hope reading this blog helps you in your projects. If you have any doubts regarding this please reach out at Twitter Happy Coding 💻