ant-design / ant-design-pro

👨🏻‍💻👩🏻‍💻 Use Ant Design like a Pro!
https://pro.ant.design
MIT License
36.13k stars 8.12k forks source link

如何在requestErrorConfig.ts中使用国际化 #11278

Open Light-yq opened 2 weeks ago

Light-yq commented 2 weeks ago

我在requestErrorConfig.ts中使用const intl = useIntl(); 编辑器提示我React Hook "useIntl" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function.

image

import type { RequestOptions } from '@@/plugin-request/request';
import type { RequestConfig } from '@umijs/max';
import { history, useIntl } from '@umijs/max';
import { message } from 'antd';
import { stringify } from 'querystring';

// eslint-disable-next-line react-hooks/rules-of-hooks

// 错误处理方案: 错误类型
enum ErrorShowType {
  SILENT = 0,
  WARN_MESSAGE = 1,
  ERROR_MESSAGE = 2,
  NOTIFICATION = 3,
  REDIRECT = 9,
}
// 与后端约定的响应数据格式
interface ResponseStructure {
  success: boolean;
  data: any;
  errorCode?: number;
  errorMessage?: string;
  showType?: ErrorShowType;
}

// 清除缓存 回到登录页
const clearStorgeGoLogin = () => {
  localStorage.removeItem('currentUser');
  const { search, pathname } = window.location;
  const urlParams = new URL(window.location.href).searchParams;
  /** 此方法会跳转到 redirect 参数所在的位置 */
  const redirect = urlParams.get('redirect');
  // Note: There may be security issues, please note
  if (window.location.pathname !== '/user/login' && !redirect) {
    history.replace({
      pathname: '/user/login',
      search: stringify({
        redirect: pathname + search,
      }),
    });
  }
};

const intl = useIntl();
/**
 * @name 错误处理
 * pro 自带的错误处理, 可以在这里做自己的改动
 * @doc https://umijs.org/docs/max/request#配置
 */
export const errorConfig: RequestConfig = {
  // 错误处理: umi@3 的错误处理方案。
  errorConfig: {
    // 错误抛出
    // errorThrower: (res) => {
    //   console.log(res, 333);
    //   const { success, data, errorCode, errorMessage, showType } =
    //     res as unknown as ResponseStructure;
    //   if (!success) {
    //     const error: any = new Error(errorMessage);
    //     error.name = 'BizError';
    //     error.info = { errorCode, errorMessage, showType, data };
    //     throw error; // 抛出自制的错误
    //   }
    // },
    // 错误接收及处理
    errorHandler: (error: any, opts: any) => {
      console.log(error);
      if (opts?.skipErrorHandler) throw error;
      if (error.message.indexOf('timeout') !== -1) {
        message.error(intl.formatMessage({ id: 'request.timeout', defaultMessage: '请求超时' }));
      }
      // 我们的 errorThrower 抛出的错误。
      message.error(error.data.message);
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestOptions) => {
      console.log(config);
      if (config.token !== false) {
        if (localStorage.getItem('currentUser')) {
          const token = JSON.parse(localStorage.getItem('currentUser')!)?.token;
          config.headers!.Authorization = `Bearer ${token}`;
        } else {
          clearStorgeGoLogin();
        }
      }
      // 拦截请求配置,进行个性化处理。
      return { ...config };
    },
  ],
  // 响应拦截器
  responseInterceptors: [
    (response) => {
      // console.log(response);
      // 拦截响应数据,进行个性化处理
      const { data } = response as unknown as ResponseStructure;
      if (data?.code === 101) {
        message.error(`${data?.message}`);
        clearStorgeGoLogin();
        return Promise.reject(response);
      } else if (data?.code !== 200) {
        return Promise.reject(response);
      }
      return response;
    },
  ],
};