Commit 49b66e83ac03ef332b6c97885e24271978171b7d
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>
Showing
5 changed files
with
72 additions
and
39 deletions
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 | }; |