Handle global error với axios
Đặt vấn đề
Khi mà làm việc với axios chúng ta sẽ luôn cần phải handle error mỗi khi server trả về lỗi hoặc thậm chí không trả về gì, tuy nhiên nếu trong trường hợp các lỗi đấy khá giống nhau thì việc lặp code là điều không thể tránh khỏi. Bài viết này sẽ hướng dẫn các bạn cách xử global error với axios mà tránh việc lặp code
Sử dụng Axios Instance
Đầu tiên các bạn tạo file axios.ts và khởi tạo một instance
import axios, { AxiosError, AxiosResponse } from 'axios';
export const API = axios.create({
baseURL: '/api',
timeout: 1000,
});
Viết một Object chuyên xử lý lỗi do axios return
export interface ComposedError {
readonly message: string;
readonly error: AxiosError;
handleGlobally(): void;
getError(): AxiosError;
}
/**
* https://medium.com/@ejjay/a-short-ajax-story-on-error-handlers-8baeeccbc062
*/
class ComposedAxiosError implements ComposedError {
name: string = 'ComposedAxiosError';
public readonly message: string;
public readonly error: AxiosError;
constructor(error: AxiosError) {
this.error = error;
const statusCode = error.response ? error.response.status : null;
switch (statusCode) {
case 401:
this.message = 'Please login to access this resource';
break;
case 404:
this.message = 'The requested resource does not exist or has been deleted';
break;
default:
this.message = 'Something went wrong and request was not completed';
}
}
public getError(): AxiosError {
return this.error;
}
public handleGlobally(): void {
toast.error(this.message); // mình dùng react-toastify để bắn noti lên client
}
}
Tiếp đó viết một error handler
/**
* Toast error if server return error
*
* @param error
* @returns
*/
const errorHandler = (error: AxiosError) => {
const composedError = new ComposedAxiosError(error);
return Promise.reject(composedError);
};
Một result handler nếu server trả về kết qủa
const resultHandler = (response: AxiosResponse) => {
if (!response?.data) {
console.error(`Data is undefined :: [${response.config.url}]`);
return response;
}
return response;
};
Tiếp đó apply chúng vào response interceptor
API.interceptors.response.use(
resultHandler,
errorHandler,
);
Done, bước kế tiếp chúng ta dùng API mà khởi tạo ở trên thay vì axios default
Cách sử dụng
import { API } from 'src/lib';
useEffect(() => {
(async () => {
try {
// do your request
} catch (error) {
// ignore since error was handled globally
error.handleGlobally();
}
})();
// Hoặc nếu không muốn dùng handle global error
try {
// do your request
} 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
} else {
error.handleGlobally();
}
}
}, []);
Kết luận
Với cách làm này chúng ta có thể tuỳ ý muốn hay không muốn dùng global error. Như vậy sẽ tiết kiệm khá nhiều thời gian cũng như việc lặp code
Comments