antd pro 有默认的响应格式,如下:
export interface response {
success: boolean; // if request is success
data?: any; // response data
errorCode?: string; // code for errorType
errorMessage?: string; // message display to user
showType?: number; // error display type: 0 silent; 1 message.warn; 2 message.error; 4 notification; 9 page
traceId?: string; // Convenient for back-end Troubleshooting: unique request ID
host?: string; // onvenient for backend Troubleshooting: host of current access server
}
但是呢,几乎没有服务端会是这样的格式,可能更多的是如下格式:
{"code":1,"message":"","data":null,"status":400}
code=业务码,message=提示信息,data=数据,status=200状态码
很多服务端api不区分状态码直接200,然后根据code做正确判断;
不管是否状态码响应,都需要将响应转换为支持的格式,需要修改处理:
//app.ts配置
export const request: RequestConfig = {
//错误出理器
errorHandler: errorHandler,
//请求拦截器,根据需要决定是否需要
requestInterceptors: [authHeaderInterceptor],
errorConfig: {
//响应体格式转换器
adaptor: errorConfigAdaptor,
}
};
//错误出理器:这段代码是plug-request 里面默认的处理,只是修改了一部分@custom
export const errorHandler = (error: RequestError) => {
//@custom
//这个是下面配置的响应体转换器
const errorAdaptor =
error?.request?.options?.errorConfig?.adaptor || ((resData: any) => resData);
const DEFAULT_ERROR_PAGE = '/exception';
// @ts-ignore
if (error?.request?.options?.skipErrorHandler) {
throw error;
}
let errorInfo: ErrorInfoStructure | undefined;
if (error.name === 'ResponseError' && error.data && error.request) {
const ctx: Context = {
req: error.request,
res: error.response,
};
errorInfo = errorAdaptor(error.data, ctx);
//@custom
//
//非标准格式或异常状态码时处理,符合标准格式转为BizError
if (errorInfo?.success === undefined) {
errorInfo = {
success: false,
errorMessage: `${ctx?.res?.statusText} (#${ctx?.res?.status})`,
};
}
error.message = errorInfo?.errorMessage || error.message;
error.data = error.data;
error.info = errorInfo;
}
errorInfo = error.info;
if (errorInfo) {
const errorMessage = errorInfo?.errorMessage;
const errorCode = errorInfo?.errorCode;
const errorPage =
error?.request?.options?.errorConfig?.errorPage || DEFAULT_ERROR_PAGE;
switch (errorInfo?.showType) {
case ErrorShowType.SILENT:
// do nothing
break;
case ErrorShowType.WARN_MESSAGE:
message.warn(errorMessage);
break;
case ErrorShowType.ERROR_MESSAGE:
message.error(errorMessage);
break;
case ErrorShowType.NOTIFICATION:
notification.open({
description: errorMessage,
message: errorCode,
});
break;
case ErrorShowType.REDIRECT:
// @ts-ignore
history.push({
pathname: errorPage,
query: {errorCode, errorMessage},
});
// redirect to error page
break;
default:
message.error(errorMessage);
break;
}
} else {
message.error(error.message || 'Request error, please retry.');
}
throw error;
}
//响应体格式转换器 这里处理后,就符合规格定时了,但是非标转异常的状态码不会处理
export const errorConfigAdaptor = (resData: any | { code: number, message: string, name?: string, data: any, status: number, [key: string]: any }, ctx) => {
if (resData?.code && resData?.status) {
return {
success: resData.status >= 200 && resData.status < 300,
//yii框架抛出异常时有name,具体可以根据服务端响应处理
errorMessage: resData?.message != '' && resData.message || resData?.name != '' && resData.name || '',
errorCode: resData?.code || '',
data: resData?.data || resData,
...resData
};
}
return resData;
};
这样的处理,request时也会抛出异常,但是有message提示;request().then(res).catch(res);
之前一直想在出理器中不抛出异常,但是当出现400等状态码时,就会进入.then(res) 这样可能会造成误判,所以还是抛出异常吧,手动catch(res)一下也不碍事;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。