umi-request 封装

1,003 阅读1分钟
import umiRequest, { RequestOptionsInit } from 'umi-request';

export const apiPrefix = '/api/v2';
export interface ServerResponse<T = any> {
  success: boolean;
  code: number;
  messageEn: string;
  message: string;

  data: T;
}

export interface APIResult<T = any> {
  error?: Error;
  resp?: ServerResponse<T>;
}

export class ResponseError extends Error {
  public url?: string;
  public response?: any;
  public body?: any;
}

const DEFAULT_REQUEST_TIMEOUT_TIME = 30000;

const HTTP_STATUS_UNAUTHORIZED = 401;

const timeoutMessage = '请求超时,请稍后重试';

export const request = (url: string, options?: RequestOptionsInit) => {
  const promise: Promise<APIResult> = new Promise((resolve) => {
    umiRequest(url, {
      ...options,
      timeout: DEFAULT_REQUEST_TIMEOUT_TIME,
      timeoutMessage,
      credentials: 'include',
      responseType: 'json',
      prefix: apiPrefix,
      errorHandler: (error) => {
        console.error(error);
        // if (response?.status !== 200) { 才会进入 errorHandler }
        if (error?.response?.status === HTTP_STATUS_UNAUTHORIZED) {
          error.message = '登录已失效,正在刷新页面';
          const delay = 1500;
          setTimeout(() => {
            window.location.reload();
          }, delay);
        } else if (error.message === 'Failed to fetch') {
          error.message = '网络异常,请检查网络';
        } else if (error.message === timeoutMessage) {
          // 什么也不做
        } else {
          error.message = '服务异常,请稍后重试';
        }
        return error;
      },
    })
      .then((resp: ServerResponse) => {
        if (resp.success) {
          resolve({
            resp,
          });
        } else {
          const err = new ResponseError(resp.message);
          err.name = String(resp.code);
          err.response = resp;
          err.body = resp.data;
          resolve({ error: err });
        }
      })
      .catch((error: Error) => {
        resolve({ error: new Error(`请求失败:${error.message}`) });
      });
  });
  return promise;
};