Pārlūkot izejas kodu

fix: errorHandler增加对使用useRequest的错误处理模式

lanjianrong 3 gadi atpakaļ
vecāks
revīzija
5ba124d8ed

+ 59 - 86
src/app.tsx

@@ -48,6 +48,24 @@ export async function getInitialState(): Promise<{
   }
 }
 
+const codeMaps = {
+  // 200: '成功返回请求的数据。',
+  201: '新建或修改数据成功。',
+  202: '一个请求已经进入后台排队(异步任务)。',
+  204: '删除数据成功。',
+  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
+  401: '用户没有权限(令牌、用户名、密码错误)。',
+  403: '用户得到授权,但是访问是被禁止的。',
+  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
+  406: '请求的格式不可得。',
+  410: '请求的资源被永久删除,且不会再得到的。',
+  422: '当创建一个对象时,发生一个验证错误。',
+  500: '服务器发生错误,请检查服务器。',
+  502: '网关错误。',
+  503: '服务不可用,服务器暂时过载或维护。',
+  504: '网关超时。'
+}
+
 const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
   const token = window.localStorage.getItem('TOKEN_ID')
   // 如果是登录页面,不执行
@@ -62,109 +80,64 @@ const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
   }
 }
 
-/**
- * 异常处理程序
- const codeMessage = {
-    200: '服务器成功返回请求的数据。',
-    201: '新建或修改数据成功。',
-    202: '一个请求已经进入后台排队(异步任务)。',
-    204: '删除数据成功。',
-    400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
-    401: '用户没有权限(令牌、用户名、密码错误)。',
-    403: '用户得到授权,但是访问是被禁止的。',
-    404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
-    405: '请求方法不被允许。',
-    406: '请求的格式不可得。',
-    410: '请求的资源被永久删除,且不会再得到的。',
-    422: '当创建一个对象时,发生一个验证错误。',
-    500: '服务器发生错误,请检查服务器。',
-    502: '网关错误。',
-    503: '服务不可用,服务器暂时过载或维护。',
-    504: '网关超时。',
- };
- * @see https://beta-pro.ant.design/docs/request-cn
- */
+// 处理非200的 http 状态码
+const responseInterceptor = response => {
+  codeMaps[response.status] &&
+    notification.error({ message: response.status, description: codeMaps[response.status] })
+  return response
+}
 export const request: RequestConfig = {
-  errorHandler: (error: ResponseError) => {
-    // const { messages } = getIntl(getLocale())
-    const { response } = error
-    if (response.code === consts.TOKEN_EXPIRED) {
-      return history.push(loginPath)
-    }
-    if (response && response.msg) {
-      // const { status, statusText, url } = response
-      // const requestErrorMessage = messages['app.request.error']
-      // const errorMessage = `${requestErrorMessage} ${status}: ${url}`
-      // const errorDescription = messages[`app.request.${status}`] || statusText
+  errorHandler: (err: ResponseError) => {
+    if (err.name === 'BizError') {
+      const response = err.data
+      if (response.code === consts.RET_CODE.SUCCESS) {
+        return response
+      }
+      if (
+        consts.TOKEN_INVALID_CODE.includes(response.code) &&
+        window.location.pathname !== loginPath
+      ) {
+        notification.error({
+          message: '用户信息过期',
+          description: '请重新登录'
+        })
+        history.replace({
+          pathname: loginPath,
+          search: stringify({
+            redirect: window.location.pathname
+          })
+        })
+      }
       notification.error({
-        message: '请求参数错误',
+        message: '请求失败',
         description: response.msg
       })
+      // 阻断代码向下执行
+      return Promise.reject(response)
     }
-
-    if (!response) {
-      notification.error({
-        description: '您的网络发生异常,无法连接服务器',
-        message: '网络异常'
-      })
+    // 那么对于其他的错误, 需要实践中一个个找出来
+    if (err.name === 'RequestError') {
+      switch (err.type) {
+        case 'Timeout': {
+          message.error('系统超时,请联系开发人员')
+        }
+      }
     }
-    throw error
+
+    return Promise.reject(err)
   },
-  // middlewares: [
-  //   async (ctx, next) => {
-  //     await next()
-  //     const { req, res } = ctx
-  //     // @ts-ignore
-  //     if (req.options?.skipErrorHandler) {
-  //       return
-  //     }
-  //     const errorAdaptor = req.options?.errorConfig.adaptor || (resData => resData)
-  //     const { options } = req
-  //     const { getResponse } = options
-  //     const resData = getResponse ? res.data : res
-  //     const errorInfo = errorAdaptor(resData, ctx)
-  //     if (resData.code !== consts.RET_CODE.SUCCESS) {
-  //       // 抛出错误到 errorHandler 中处理
-  //       const error = new Error(errorInfo.errorMessage)
-  //       error.name = 'BizError'
-  //       error.data = resData
-  //       error.info = errorInfo
-  //       error.response = res
-  //       throw error
-  //     }
-  //   }
-  // ],
   prefix: '/api',
   errorConfig: {
     adaptor: resData => {
       return {
-        // success: resData.code === consts.RET_CODE.SUCCESS,
+        success: resData.code === consts.RET_CODE.SUCCESS,
         data: resData.data,
         errorCode: resData.code,
         errorMessage: resData.msg
       }
     }
   },
-  responseInterceptors: [
-    async (response, options) => {
-      const errorAdaptor = options?.errorConfig.adaptor || (resData => resData)
-      const res = await response.clone().json()
-      const { getResponse } = options
-      const resData = getResponse ? res.data : res
-      const errorInfo = errorAdaptor(resData, { res: response, req: options })
-
-      if (res?.code !== consts.RET_CODE.SUCCESS) {
-        // 抛出错误到 errorHandler 中处理
-        const error = new Error(errorInfo.errorMessage?.toString())
-        error.name = 'BizError'
-        error.data = resData
-        error.info = errorInfo
-        error.response = res
-        throw error
-      }
-      return response
-    }
-  ],
+  responseInterceptors: [responseInterceptor],
   requestInterceptors: [authHeaderInterceptor]
 }
 

+ 9 - 12
src/pages/Institutions/Staff/components/StaffDetail.tsx

@@ -77,7 +77,8 @@ const StaffDrawer: React.FC<StaffModalProps> = ({
     manual: true,
     onSuccess: () => {
       message.success('创建成功')
-    }
+    },
+    throwOnError: true
   })
 
   useEffect(() => {
@@ -93,18 +94,14 @@ const StaffDrawer: React.FC<StaffModalProps> = ({
 
   const onFinish = async formData => {
     if ('institution' in formData) delete formData.institution
-    try {
-      // 执行表单提交
-      if (type === ModalType.ADD) {
-        await tryAddAccount(formData)
-      } else {
-        await tryUpdateAccount({ ...formData, ID: defaultFormData.ID })
-      }
-      onVisibleChange(false)
-      reload()
-    } catch (error) {
-      message.error(error)
+    // 执行表单提交
+    if (type === ModalType.ADD) {
+      await tryAddAccount(formData)
+    } else {
+      await tryUpdateAccount({ ...formData, ID: defaultFormData.ID })
     }
+    onVisibleChange(false)
+    reload()
   }
   const normalForm = useMemo(
     () =>

+ 1 - 1
src/utils/consts.ts

@@ -3,5 +3,5 @@ export default {
     SUCCESS: 0,
     ERROR: -1
   },
-  TOKEN_EXPIRED: 2
+  TOKEN_INVALID_CODE: [2]
 }