Files
SMATEC-FRONTEND/config/request_dev.ts
2026-01-21 11:48:57 +07:00

132 lines
4.2 KiB
TypeScript

import { HTTPSTATUS } from '@/constants';
import { ROUTE_LOGIN } from '@/constants/routes';
import { getToken, removeToken } from '@/utils/storage';
import { history, RequestConfig } from '@umijs/max';
import { message } from 'antd';
// Error handling scheme: Error types
// enum ErrorShowType {
// SILENT = 0,
// WARN_MESSAGE = 1,
// ERROR_MESSAGE = 2,
// NOTIFICATION = 3,
// REDIRECT = 9,
// }
// Response data structure agreed with the backend
// interface ResponseStructure<T = any> {
// success: boolean;
// data: T;
// errorCode?: number;
// errorMessage?: string;
// showType?: ErrorShowType;
// }
// const codeMessage = {
// 200: 'The server successfully returned the requested data。',
// 201: 'New or modified data succeeded。',
// 202: 'A request has been queued in the background (asynchronous task)。',
// 204: 'Data deleted successfully。',
// 400: 'There is an error in the request sent, the server did not perform the operation of creating or modifying data。',
// 401: 'The user does not have permission (token, username, password is wrong) 。',
// 403: 'User is authorized, but access is prohibited。',
// 404: 'The request issued was for a non-existent record, the server did not operate。',
// 406: 'The requested format is not available。',
// 410: 'The requested resource is permanently deleted and will no longer be available。',
// 422: 'When creating an object, a validation error occurred。',
// 500: 'Server error, please check the server。',
// 502: 'Gateway error。',
// 503: 'Service unavailable, server temporarily overloaded or maintained。',
// 504: 'Gateway timeout。',
// };
// Runtime configuration
export const handleRequestConfig: RequestConfig = {
// Unified request settings
timeout: 20000,
validateStatus: (status) => {
return (
(status >= 200 && status < 300) || status === HTTPSTATUS.HTTP_NOTFOUND
);
},
headers: { 'X-Requested-With': 'XMLHttpRequest' },
// Error handling: umi@3's error handling scheme.
errorConfig: {
// Error throwing
errorThrower: (res: any) => {
// console.log('Response from backend:', res);
const { success, data, errorCode, errorMessage, showType } = res;
if (!success) {
const error: any = new Error(errorMessage);
error.name = 'BizError';
error.info = { errorCode, errorMessage, showType, data };
throw error; // Throw custom error
}
},
// Error catching and handling
errorHandler: (error: any) => {
if (error.response) {
const { status } = error.response;
// Ưu tiên: codeMessage → backend message → statusText
// const errMsg =
// codeMessage[status as keyof typeof codeMessage] ||
// data?.message ||
// statusText ||
// 'Unknown error';
if (status === HTTPSTATUS.HTTP_UNAUTHORIZED) {
removeToken();
history.push(ROUTE_LOGIN);
} else if (status === HTTPSTATUS.HTTP_SERVERERROR) {
// message.error('💥 Internal server error!');
} else {
message.error(`${status}: ${error.message || 'Error'}`);
}
} else if (error.request) {
message.error('🚨 No response from server!');
} else {
message.error(`⚠️ Request setup error: ${error.message}`);
}
},
},
// Request interceptors
requestInterceptors: [
(url: string, options: any) => {
const token = getToken();
// console.log('Token: ', token);
return {
url,
options: {
...options,
headers: {
...options.headers,
...(token ? { Authorization: `${token}` } : {}),
},
},
};
},
],
// Unwrap data from backend response
responseInterceptors: [
(response) => {
// console.log('Response from server: ', response);
// const res = response.data as ResponseStructure<any>;
// if (res && res.success) {
// // ✅ Trả ra data luôn thay vì cả object
// return res.data;
// }
return {
status: response.status,
statusText: response.statusText,
headers: response.headers,
config: response.config,
data: response.data,
};
},
],
};