Open GitKou opened 3 years ago
我的问题和这个issue里的类似,https://github.com/umijs/umi-request/issues/18 评论中说用拦截器去抛出异常处理,但是在errorHandler中拿到的response是null,那么就无法根据code,做出相应的文案错误提示
最后这么处理的,不知道有没有更标准的写法
结合了https://github.com/blueju/umi-request-practice 这个库,整理了下,最终如下
/** request.ts**/
/** Request 网络请求工具 更详细的 api 文档: https://github.com/umijs/umi-request */
import { notification } from 'antd';
import { extend } from 'umi-request';
import store from 'store';
import type {
RequestInterceptor,
RequestOptionsInit,
ResponseError,
ResponseInterceptor,
} from 'umi-request';
import type { AjaxData } from '@/common';
import { HttpError, SystemError } from './error-type';
/** 异常处理程序 */
const errorHandler = (error: ResponseError) => {
// 网络异常
if (error.message === 'Failed to fetch') {
notification.error({
message: '网络异常',
description: `${error.message}:${error?.request?.url}`,
});
// 阻断执行,并将错误信息传递下去
return Promise.reject(error);
}
// HTTP 错误
if (error.name === 'HttpError') {
notification.error({
message: 'HTTP 错误',
description: error.message,
});
return Promise.reject(error);
}
// 系统错误
if (error.name === 'SystemError') {
notification.error({
message: '系统错误',
description: error.message,
});
return Promise.reject(error);
}
// 前置错误
if (error.name === 'PremiseError') {
notification.error({
message: '前置错误',
description: error.message,
});
return Promise.reject(error);
}
notification.error({
message: '其他错误',
description: error.message,
});
return Promise.reject(error);
};
const authHeaderInterceptor: RequestInterceptor = (url: string, options: RequestOptionsInit) => {
const token = store.get('token');
const { headers, ...rest } = options;
return {
url,
options: {
...rest,
headers: {
...headers,
'access-token': token,
},
},
};
};
const errorInterceptors: ResponseInterceptor = async (response) => {
if (response.status === 200) {
return response
.clone()
.json()
.then((responseJson: AjaxData<any>) => {
const code = responseJson?.code;
if (code === '200') {
return response;
}
throw new SystemError(`${code} ${responseJson.message} ${response.url}`, code);
});
}
throw new HttpError(`${response.status} ${response.statusText} ${response.url}`);
};
/** 配置request请求时的默认参数 */
const request = extend({
responseType: 'json',
errorHandler, // 默认错误处理
credentials: 'include', // 默认请求是否带上cookie
});
request.interceptors.request.use(authHeaderInterceptor);
request.interceptors.response.use(errorInterceptors);
export default request;
/** error-type.ts */
/* eslint-disable max-classes-per-file */
/**
* HTTP 错误,除网络错误、http 状态码为 200 以外的错误
*/
export class HttpError extends Error {
constructor(message: string) {
super(message);
this.name = this.constructor.name;
}
}
/**
* 系统错误,http 状态码为 200,但响应数据中 res.code !== '200'的错误
*/
export class SystemError extends Error {
code: string
constructor(message: string, code: string) {
super(message);
this.name = this.constructor.name;
this.code = code;
}
}
/**
* Premise Error
* 前提错误
* 如:全局常量不存在,用户信息不存在,Token 不存在等
*/
export class PremiseError extends Error {
constructor(message: string) {
super(message);
this.name = this.constructor.name;
}
}
自问自答可还行 ,最新一次close是五月份了:(
还是给了我一些参考 感谢
自问自答可还行 ,最新一次close是五月份了:(
给你点个赞 👻
我在responseInterceptors中抛出code!==200的错误,但是在errorhandler打印出response为null, 希望能在errorhandler中区分出http status!==200 和 业务错误码code!=='200'的两种错误, 我现在可以通过error.message这样区分,请问怎么才能区分毕竟合理?
request.interceptors.response.use(errorInterceptors);