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