refactor(web): 优化 API 请求拦截器和错误处理

- 重构了 API 请求拦截器,提高了错误处理的可读性和可维护性
- 添加了单独的 showErrorNotification 函数来显示错误通知
- 优化了 AxiosError 的处理逻辑
- 调整了错误信息的处理和显示方式
main
Tuzki 5 months ago
parent 8f89b359ee
commit f439a9fe7b
  1. 59
      web/client/api/tools/interceptors.ts
  2. 4
      web/next.config.js
  3. 44
      web/pages/_app.tsx

@ -2,54 +2,57 @@ import { notification } from 'antd';
import { AxiosError } from 'axios';
import { ApiResponse } from '../';
/**
*
*/
const showErrorNotification = (title: string, description: string) => {
notification.error({
message: title,
description,
});
};
/**
* API useRequest.onError
*/
export const apiInterceptors = async <T = any, D = any, R = any>(
promise: Promise<ApiResponse<T, D>>,
): Promise<[null, T, R] | [Error, null, R]> => {
): Promise<[null, T, R] | [Error, null, null]> => {
try {
const response = await promise;
const { data } = response;
if (!data.success) {
const error = new Error(data.err_msg || '未知错误');
(error as any).code = data.err_code;
(error as any).raw = data;
notification.error({
message: '请求失败',
description: data.err_msg || '接口异常,请重试',
Object.assign(error, {
code: data.err_code,
raw: data,
});
showErrorNotification('请求失败', data.err_msg || '接口异常,请重试');
return [error, null, null];
}
return [null, data.data,response.data];
} catch (err: any) {
return [null, data.data, response.data];
} catch (err) {
let error: Error;
let errMsg = '未知错误';
if (err.isAxiosError) {
if (err instanceof AxiosError) {
error = new Error('网络请求异常');
} else {
error = err;
}
let errMsg = '接口异常';
if (err instanceof AxiosError && err.request.response) {
try {
const parsedResponse = JSON.parse(err.request.response);
errMsg = parsedResponse?.err_msg ?? '接口异常';
} catch (parseError) {
console.error('JSON 解析失败', parseError);
if (err.request?.response) {
try {
const parsedResponse = JSON.parse(err.request.response);
errMsg = parsedResponse.err_msg ?? '接口异常';
} catch (parseError) {
console.error('JSON 解析失败', parseError);
}
}
} else {
errMsg = err.message;
error = err instanceof Error ? err : new Error('未知错误');
errMsg = error.message;
}
notification.error({
message: '请求异常',
description: errMsg,
});
return [error, null];
showErrorNotification('请求异常', errMsg);
return [error, null, null];
}
};
};

@ -33,6 +33,10 @@ const nextConfig = {
webpack: (config, { isServer }) => {
config.resolve.fallback = { fs: false };
if (!isServer) {
config.optimization.runtimeChunk = 'single';
config.watchOptions = {
ignored: ['**/node_modules', '**/.git'],
};
config.plugins.push(
new CopyPlugin({
patterns: [

@ -115,31 +115,31 @@ function LayoutWrapper({ children }: { children: React.ReactNode }) {
};
const { pathname } = useRouter();
const { run: getUserMenuFun } = useRequest(
async () => {
if (pathname.startsWith('/login')) return;
return await getUserMenu(); // 直接传递表单对象
},
{
manual: false,
onSuccess: res => {
if (!res) return;
const { data } = res;
console.log('getUserMenu', data);
localStorage.setItem('menu', JSON.stringify(data.data));
// localStorage.setItem('menu', JSON.stringify(menuRes.data.data));
// console.log('menuRes', menuRes);
},
onError: error => {
console.log('error', error);
},
debounceWait: 500,
},
);
// const { run: getUserMenuFun } = useRequest(
// async () => {
// if (pathname.startsWith('/login')) return;
// return await getUserMenu(); // 直接传递表单对象
// },
// {
// manual: false,
// onSuccess: res => {
// if (!res) return;
// const { data } = res;
// console.log('getUserMenu', data);
// localStorage.setItem('menu', JSON.stringify(data.data));
// // localStorage.setItem('menu', JSON.stringify(menuRes.data.data));
// // console.log('menuRes', menuRes);
// },
// onError: error => {
// console.log('error', error);
// },
// debounceWait: 500,
// },
// );
// 在组件挂载时调用handleAuth函数
useEffect(() => {
handleAuth();
getUserMenuFun();
// getUserMenuFun();
}, [router.pathname]);
if (!authChecked) {
// 增加加载状态

Loading…
Cancel
Save