Commit 49b66e83ac03ef332b6c97885e24271978171b7d

Authored by xlaoyu
Committed by GitHub
1 parent ab2c7efe

refactor(axios): control the display of common errors in the request cycle (#758)

Co-authored-by: frankylli <frankylli@tencent.com>
src/locales/lang/zh_CN/sys.ts
... ... @@ -7,7 +7,7 @@ export default {
7 7 apiTimeoutMessage: '接口请求超时,请刷新页面重试!',
8 8 apiRequestFailed: '请求出错,请稍候重试',
9 9 networkException: '网络异常',
10   - networkExceptionMsg: '请检查您的网络连接是否正常!',
  10 + networkExceptionMsg: '网络异常,请检查您的网络连接是否正常!',
11 11  
12 12 errMsg401: '用户没有权限(令牌、用户名、密码错误)!',
13 13 errMsg403: '用户得到授权,但是访问是被禁止的。!',
... ...
src/utils/http/axios/Axios.ts
... ... @@ -188,7 +188,7 @@ export class VAxios {
188 188 }
189 189  
190 190 request<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
191   - let conf: AxiosRequestConfig = cloneDeep(config);
  191 + let conf: CreateAxiosOptions = cloneDeep(config);
192 192 const transform = this.getTransform();
193 193  
194 194 const { requestOptions } = this.options;
... ... @@ -199,6 +199,7 @@ export class VAxios {
199 199 if (beforeRequestHook && isFunction(beforeRequestHook)) {
200 200 conf = beforeRequestHook(conf, opt);
201 201 }
  202 + conf.requestOptions = opt;
202 203  
203 204 conf = this.supportFormData(conf);
204 205  
... ... @@ -219,7 +220,7 @@ export class VAxios {
219 220 })
220 221 .catch((e: Error) => {
221 222 if (requestCatchHook && isFunction(requestCatchHook)) {
222   - reject(requestCatchHook(e));
  223 + reject(requestCatchHook(e, opt));
223 224 return;
224 225 }
225 226 reject(e);
... ...
src/utils/http/axios/axiosTransform.ts
... ... @@ -25,7 +25,7 @@ export abstract class AxiosTransform {
25 25 /**
26 26 * @description: 请求失败处理
27 27 */
28   - requestCatchHook?: (e: Error) => Promise<any>;
  28 + requestCatchHook?: (e: Error, options: RequestOptions) => Promise<any>;
29 29  
30 30 /**
31 31 * @description: 请求之前的拦截器
... ...
src/utils/http/axios/checkStatus.ts
  1 +import type { ErrorMessageMode } from './types';
  2 +
1 3 import { useMessage } from '/@/hooks/web/useMessage';
2 4 import { useI18n } from '/@/hooks/web/useI18n';
3 5 // import router from '/@/router';
4 6 // import { PageEnum } from '/@/enums/pageEnum';
5 7 import { useUserStoreWidthOut } from '/@/store/modules/user';
6 8  
7   -const { createMessage } = useMessage();
  9 +const { createMessage, createErrorModal } = useMessage();
8 10  
9 11 const error = createMessage.error!;
10   -export function checkStatus(status: number, msg: string): void {
  12 +export function checkStatus(
  13 + status: number,
  14 + msg: string,
  15 + errorMessageMode: ErrorMessageMode = 'message'
  16 +): void {
11 17 const { t } = useI18n();
12 18 const userStore = useUserStoreWidthOut();
  19 + let errMessage = '';
  20 +
13 21 switch (status) {
14 22 case 400:
15   - error(`${msg}`);
  23 + errMessage = `${msg}`;
16 24 break;
17 25 // 401: Not logged in
18 26 // Jump to the login page if not logged in, and carry the path of the current page
19 27 // Return to the current page after successful login. This step needs to be operated on the login page.
20 28 case 401:
21   - error(t('sys.api.errMsg401'));
  29 + errMessage = t('sys.api.errMsg401');
22 30 userStore.setToken(undefined);
23 31 userStore.setSessionTimeout(true);
24 32 break;
25 33 case 403:
26   - error(t('sys.api.errMsg403'));
  34 + errMessage = t('sys.api.errMsg403');
27 35 break;
28 36 // 404请求不存在
29 37 case 404:
30   - error(t('sys.api.errMsg404'));
  38 + errMessage = t('sys.api.errMsg404');
31 39 break;
32 40 case 405:
33   - error(t('sys.api.errMsg405'));
  41 + errMessage = t('sys.api.errMsg405');
34 42 break;
35 43 case 408:
36   - error(t('sys.api.errMsg408'));
  44 + errMessage = t('sys.api.errMsg408');
37 45 break;
38 46 case 500:
39   - error(t('sys.api.errMsg500'));
  47 + errMessage = t('sys.api.errMsg500');
40 48 break;
41 49 case 501:
42   - error(t('sys.api.errMsg501'));
  50 + errMessage = t('sys.api.errMsg501');
43 51 break;
44 52 case 502:
45   - error(t('sys.api.errMsg502'));
  53 + errMessage = t('sys.api.errMsg502');
46 54 break;
47 55 case 503:
48   - error(t('sys.api.errMsg503'));
  56 + errMessage = t('sys.api.errMsg503');
49 57 break;
50 58 case 504:
51   - error(t('sys.api.errMsg504'));
  59 + errMessage = t('sys.api.errMsg504');
52 60 break;
53 61 case 505:
54   - error(t('sys.api.errMsg505'));
  62 + errMessage = t('sys.api.errMsg505');
55 63 break;
56 64 default:
57 65 }
  66 +
  67 + if (errMessage) {
  68 + if (errorMessageMode === 'modal') {
  69 + createErrorModal({ title: t('sys.api.errorTip'), content: errMessage });
  70 + } else if (errorMessageMode === 'message') {
  71 + error(errMessage);
  72 + }
  73 + }
58 74 }
... ...
src/utils/http/axios/index.ts
... ... @@ -62,26 +62,25 @@ const transform: AxiosTransform = {
62 62  
63 63 // 在此处根据自己项目的实际情况对不同的code执行不同的操作
64 64 // 如果不希望中断当前请求,请return数据,否则直接抛出异常即可
  65 + let timeoutMsg = '';
65 66 switch (code) {
66 67 case ResultEnum.TIMEOUT:
67   - const timeoutMsg = t('sys.api.timeoutMessage');
68   - createErrorModal({
69   - title: t('sys.api.operationFailed'),
70   - content: timeoutMsg,
71   - });
72   - throw new Error(timeoutMsg);
  68 + timeoutMsg = t('sys.api.timeoutMessage');
73 69 default:
74 70 if (message) {
75   - // errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
76   - // errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
77   - if (options.errorMessageMode === 'modal') {
78   - createErrorModal({ title: t('sys.api.errorTip'), content: message });
79   - } else if (options.errorMessageMode === 'message') {
80   - createMessage.error(message);
81   - }
  71 + timeoutMsg = message;
82 72 }
83 73 }
84   - throw new Error(message || t('sys.api.apiRequestFailed'));
  74 +
  75 + // errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
  76 + // errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
  77 + if (options.errorMessageMode === 'modal') {
  78 + createErrorModal({ title: t('sys.api.errorTip'), content: timeoutMsg });
  79 + } else if (options.errorMessageMode === 'message') {
  80 + createMessage.error(timeoutMsg);
  81 + }
  82 +
  83 + throw new Error(timeoutMsg || t('sys.api.apiRequestFailed'));
85 84 },
86 85  
87 86 // 请求之前处理config
... ... @@ -136,29 +135,46 @@ const transform: AxiosTransform = {
136 135 },
137 136  
138 137 /**
  138 + * @description: 响应拦截器处理
  139 + */
  140 + responseInterceptors: (res: AxiosResponse<any>) => {
  141 + return res;
  142 + },
  143 +
  144 + /**
139 145 * @description: 响应错误处理
140 146 */
141 147 responseInterceptorsCatch: (error: any) => {
142 148 const { t } = useI18n();
143 149 const errorLogStore = useErrorLogStoreWithOut();
144 150 errorLogStore.addAjaxErrorInfo(error);
145   - const { response, code, message } = error || {};
  151 + const { response, code, message, config } = error || {};
  152 + const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
146 153 const msg: string = response?.data?.error?.message ?? '';
147 154 const err: string = error?.toString?.() ?? '';
  155 + let errMessage = '';
  156 +
148 157 try {
149 158 if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
150   - createMessage.error(t('sys.api.apiTimeoutMessage'));
  159 + errMessage = t('sys.api.apiTimeoutMessage');
151 160 }
152 161 if (err?.includes('Network Error')) {
153   - createErrorModal({
154   - title: t('sys.api.networkException'),
155   - content: t('sys.api.networkExceptionMsg'),
156   - });
  162 + errMessage = t('sys.api.networkExceptionMsg');
  163 + }
  164 +
  165 + if (errMessage) {
  166 + if (errorMessageMode === 'modal') {
  167 + createErrorModal({ title: t('sys.api.errorTip'), content: errMessage });
  168 + } else if (errorMessageMode === 'message') {
  169 + createMessage.error(errMessage);
  170 + }
  171 + return Promise.reject(error);
157 172 }
158 173 } catch (error) {
159 174 throw new Error(error);
160 175 }
161   - checkStatus(error?.response?.status, msg);
  176 +
  177 + checkStatus(error?.response?.status, msg, errorMessageMode);
162 178 return Promise.reject(error);
163 179 },
164 180 };
... ...