106 lines
3.5 KiB
TypeScript
106 lines
3.5 KiB
TypeScript
import { ROUTE_LOGIN } from '@/constants';
|
|
import { apiConfig } from '@/services/ApiConfigService';
|
|
import { getToken, removeToken } from '@/utils/localStorageUtils';
|
|
import { history, RequestConfig } from '@umijs/max';
|
|
import { message } from 'antd';
|
|
|
|
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,
|
|
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, statusText, data } = error.response;
|
|
|
|
// Ưu tiên: codeMessage → backend message → statusText
|
|
const errMsg =
|
|
codeMessage[status as keyof typeof codeMessage] ||
|
|
data?.message ||
|
|
statusText ||
|
|
'Unknown error';
|
|
|
|
message.error(`❌ ${status}: ${errMsg}`);
|
|
if (status === 401) {
|
|
removeToken();
|
|
history.push(ROUTE_LOGIN);
|
|
}
|
|
} 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) => {
|
|
console.log('URL Request:', url, options);
|
|
|
|
// Nếu URL không phải absolute URL, thêm base URL
|
|
let finalUrl = url;
|
|
if (!url.startsWith('http')) {
|
|
const baseUrl = apiConfig.getApiBaseUrl();
|
|
finalUrl = `${baseUrl}${url}`;
|
|
}
|
|
|
|
const token = getToken();
|
|
return {
|
|
url: finalUrl,
|
|
options: {
|
|
...options,
|
|
headers: {
|
|
...options.headers,
|
|
...(token ? { Authorization: `${token}` } : {}),
|
|
},
|
|
},
|
|
};
|
|
},
|
|
],
|
|
|
|
// Unwrap data from backend response
|
|
// responseInterceptors: [
|
|
// (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 response.data;
|
|
// },
|
|
// ],
|
|
};
|