1. 19:09 14/10/2026
## Giới thiệu
Khi phát triển một monorepo chứa cả ứng dụng web (Next.js) và mobile (React Native), việc xử lý lỗi API một cách nhất quán giúp giảm thiểu mã lặp, dễ dàng bảo trì và cải thiện trải nghiệm người dùng. Bài viết này chia sẻ cách xây dựng một lớp xử lý lỗi tập trung kết hợp với chiến lược retry thông minh, áp dụng cho Axios và React Query.
## 1. Tạo instance Axios chung
- Khởi tạo một file `api/client.ts` export một instance Axios đã cấu hình `baseURL`, `timeout` và header mặc định.
- Gắn interceptor `request` để thêm token xác thực từ store (Zustand/Redux) vào header `Authorization`.
- Gắn interceptor `response`:
- Nếu status 401 → tự động refresh token (nếu có) và retry request gốc một lần.
- Nếu status 4xx/5xx → chuẩn hóa đối tượng lỗi `{ code, message, details }` và ném ra để React Query bắt.
## 2. Cấu hình React Query mặc định
Trong `queryClient.ts` thiết lập `defaultOptions`:
- `retry: 3` cho các query/mutation idempotent (GET, HEAD).
- `retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000)` – exponential backoff với giới hạn 30 giây.
- `onError: (error) => { logError(error); showToast(error.message); }` – ghi log tập trung và hiển thị toast thống nhất.
## 3. Hook tùy chỉnh `useApi`
```ts
export const useApi = () => {
const queryClient = useQueryClient();
const mutate = useMutation(apiClient.post, {
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['list'] }),
onError: (err) => {
// Xử lý riêng cho mutation nếu cần
},
});
return { mutate };
};
```
Hook này gói gọn logic gọi API, tự động áp dụng retry và invalidation cache.
## 4. Logging và monitoring tập trung
- Sử dụng `pino` (Node) hoặc `react-native-logs` (mobile) để ghi lỗi ra stdout / file.
- Gửi log lên OpenTelemetry collector → Grafana Loki để truy vấn và cảnh báo.
## 5. Kiểm thử chiến lược retry
- Viết test với `msw` (Mock Service Worker) giả lập lỗi 500, 429, network timeout.
- Kiểm tra số lần gọi lại, độ trễ giữa các lần, và kết quả cuối cùng (thành công hoặc thất bại sau 3 lần).
## 6. Lợi ích thực tế
- Giảm 70 % boilerplate xử lý lỗi trong từng component.
- Người dùng thấy toast thống nhất, không bị mất trạng thái loading.
- Dễ dàng điều chỉnh chính sách retry toàn hệ thống chỉ bằng một file config.
## Kết luận
Việc tập trung xử lý lỗi và retry tại lớp network (Axios) và lớp data fetching (React Query) mang lại mã sạch, nhất quán và dễ mở rộng cho cả web lẫn mobile trong monorepo. Hãy áp dụng mẫu này ngay hôm nay để nâng cao độ bền vững của ứng dụng.