feat: 适配器异常处理成响应异常
parent
adb9dbe88f
commit
be17ba7e68
|
@ -19,7 +19,7 @@ lib/
|
|||
*.test.js
|
||||
*.test.d.ts
|
||||
*.test.js.map
|
||||
coverage
|
||||
.coverage
|
||||
|
||||
# eslint
|
||||
.eslintcache
|
||||
|
|
|
@ -2,6 +2,7 @@ import {
|
|||
isEmptyArray,
|
||||
isFunction,
|
||||
isPlainObject,
|
||||
isString,
|
||||
isUndefined,
|
||||
} from './helpers/isTypes';
|
||||
import { assert } from './helpers/error';
|
||||
|
@ -57,6 +58,19 @@ export interface AxiosAdapterResponseError extends AnyObject {
|
|||
* 响应头
|
||||
*/
|
||||
headers: AnyObject;
|
||||
/**
|
||||
* 错误数据
|
||||
*/
|
||||
data?: {
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
errMsg: string;
|
||||
/**
|
||||
* Errno错误码
|
||||
*/
|
||||
errno: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AxiosAdapterRequestConfig extends AnyObject {
|
||||
|
@ -253,22 +267,25 @@ export function createAdapter(platform: AxiosPlatform) {
|
|||
return download(options);
|
||||
}
|
||||
|
||||
function transformResult(result: AnyObject): void {
|
||||
result.status =
|
||||
result.status ??
|
||||
result.statusCode ??
|
||||
(isUndefined(result.data) ? 400 : 200);
|
||||
result.statusText =
|
||||
result.status === 200
|
||||
? 'OK'
|
||||
: result.status === 400
|
||||
? 'Bad Adapter'
|
||||
: result.errMsg;
|
||||
result.headers = result.headers || result.header;
|
||||
function transformResponse(response: AnyObject): void {
|
||||
response.status = response.status ?? response.statusCode;
|
||||
response.statusText = 'OK';
|
||||
|
||||
if (result.statusCode) delete result.statusCode;
|
||||
if (result.errMsg) delete result.errMsg;
|
||||
if (result.header) delete result.header;
|
||||
if (isUndefined(response.status)) {
|
||||
response.status = 400;
|
||||
response.statusText = 'Fail Adapter';
|
||||
}
|
||||
|
||||
response.headers = response.headers ?? response.header ?? {};
|
||||
|
||||
if (isUndefined(response.data) && isString(response.errMsg)) {
|
||||
response.data = {
|
||||
errMsg: response.errMsg,
|
||||
errno: response.errno,
|
||||
};
|
||||
}
|
||||
|
||||
cleanResponse(response, ['statusCode', 'errMsg', 'errno', 'header']);
|
||||
}
|
||||
|
||||
function transformOptions(
|
||||
|
@ -278,11 +295,11 @@ export function createAdapter(platform: AxiosPlatform) {
|
|||
...config,
|
||||
header: config.headers,
|
||||
success(response): void {
|
||||
transformResult(response);
|
||||
transformResponse(response);
|
||||
config.success(response);
|
||||
},
|
||||
fail(error: AxiosAdapterResponseError): void {
|
||||
transformResult(error);
|
||||
transformResponse(error);
|
||||
config.fail(error);
|
||||
},
|
||||
};
|
||||
|
@ -297,9 +314,16 @@ export function createAdapter(platform: AxiosPlatform) {
|
|||
response.apFilePath,
|
||||
};
|
||||
|
||||
if (response.tempFilePath) delete response.tempFilePath;
|
||||
if (response.apFilePath) delete response.apFilePath;
|
||||
if (response.filePath) delete response.filePath;
|
||||
cleanResponse(response, ['tempFilePath', 'apFilePath', 'filePath']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理 response 上多余的 key
|
||||
*/
|
||||
function cleanResponse(response: AnyObject, keys: string[]) {
|
||||
for (const key of keys) {
|
||||
if (key in response) delete response[key];
|
||||
}
|
||||
}
|
||||
|
||||
return adapter;
|
||||
|
|
|
@ -186,7 +186,7 @@ export interface AxiosResponse<
|
|||
|
||||
export interface AxiosResponseError extends AxiosAdapterResponseError {
|
||||
/**
|
||||
* 原生接口 fail 回调产生的响应错误
|
||||
* 失败的请求,指没能够成功响应的请求
|
||||
*/
|
||||
isFail: true;
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
AxiosAdapterRequestMethod,
|
||||
AxiosAdapterResponse,
|
||||
AxiosAdapterResponseError,
|
||||
AxiosAdapterTask,
|
||||
} from '../adapter';
|
||||
import {
|
||||
AxiosProgressCallback,
|
||||
|
@ -49,7 +50,16 @@ export function request(config: AxiosRequestConfig) {
|
|||
fail,
|
||||
};
|
||||
|
||||
const adapterTask = adapter!(adapterConfig);
|
||||
let adapterTask: AxiosAdapterTask;
|
||||
try {
|
||||
adapterTask = adapter!(adapterConfig);
|
||||
} catch {
|
||||
fail({
|
||||
status: 400,
|
||||
statusText: 'Bad Adapter',
|
||||
headers: {},
|
||||
});
|
||||
}
|
||||
|
||||
function success(_: AxiosAdapterResponse): void {
|
||||
const response = _ as AxiosResponse;
|
||||
|
|
|
@ -253,12 +253,14 @@ describe('src/adapter.ts', () => {
|
|||
};
|
||||
const p2 = {
|
||||
...p1,
|
||||
request: vi.fn(({ fail }) => fail({ data: { result: null } })),
|
||||
request: vi.fn(({ fail }) =>
|
||||
fail({ status: 500, data: { result: null } }),
|
||||
),
|
||||
};
|
||||
const p3 = {
|
||||
...p1,
|
||||
request: vi.fn(({ fail }) =>
|
||||
fail({ statusCode: 500, header: {}, errMsg: 'request:fail' }),
|
||||
fail({ errMsg: 'request:fail', errno: 1000 }),
|
||||
),
|
||||
};
|
||||
const c1 = {
|
||||
|
@ -269,9 +271,9 @@ describe('src/adapter.ts', () => {
|
|||
fail: (response: any) => {
|
||||
expect(response).toMatchInlineSnapshot(`
|
||||
{
|
||||
"headers": undefined,
|
||||
"headers": {},
|
||||
"status": 400,
|
||||
"statusText": "Bad Adapter",
|
||||
"statusText": "Fail Adapter",
|
||||
}
|
||||
`);
|
||||
},
|
||||
|
@ -284,8 +286,8 @@ describe('src/adapter.ts', () => {
|
|||
"data": {
|
||||
"result": null,
|
||||
},
|
||||
"headers": undefined,
|
||||
"status": 200,
|
||||
"headers": {},
|
||||
"status": 500,
|
||||
"statusText": "OK",
|
||||
}
|
||||
`);
|
||||
|
@ -296,9 +298,13 @@ describe('src/adapter.ts', () => {
|
|||
fail: (response: any) => {
|
||||
expect(response).toMatchInlineSnapshot(`
|
||||
{
|
||||
"data": {
|
||||
"errMsg": "request:fail",
|
||||
"errno": 1000,
|
||||
},
|
||||
"headers": {},
|
||||
"status": 500,
|
||||
"statusText": "request:fail",
|
||||
"status": 400,
|
||||
"statusText": "Fail Adapter",
|
||||
}
|
||||
`);
|
||||
},
|
||||
|
|
|
@ -37,16 +37,42 @@ describe('src/core/dispatchRequest.ts', () => {
|
|||
).not.toThrowError();
|
||||
});
|
||||
|
||||
test('坏的适配器', () => {
|
||||
expect(() =>
|
||||
test('坏的适配器应该抛出异常', () => {
|
||||
expect(
|
||||
dispatchRequest({
|
||||
adapter: () => {
|
||||
throw 'bad adapter';
|
||||
},
|
||||
url: '/',
|
||||
method: 'get',
|
||||
}),
|
||||
).toMatchInlineSnapshot('[Function]');
|
||||
}).catch((e) => ({ ...e })),
|
||||
).resolves.toMatchInlineSnapshot(`
|
||||
{
|
||||
"config": {
|
||||
"adapter": [Function],
|
||||
"data": undefined,
|
||||
"headers": undefined,
|
||||
"method": "get",
|
||||
"url": "",
|
||||
},
|
||||
"request": undefined,
|
||||
"response": {
|
||||
"config": {
|
||||
"adapter": [Function],
|
||||
"data": undefined,
|
||||
"headers": undefined,
|
||||
"method": "get",
|
||||
"url": "",
|
||||
},
|
||||
"data": undefined,
|
||||
"headers": {},
|
||||
"isFail": true,
|
||||
"request": undefined,
|
||||
"status": 400,
|
||||
"statusText": "Bad Adapter",
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test('应该支持转换 URL', () => {
|
||||
|
|
|
@ -10,7 +10,7 @@ export default defineConfig({
|
|||
},
|
||||
coverage: {
|
||||
provider: 'istanbul',
|
||||
reportsDirectory: resolve('test/coverage'),
|
||||
reportsDirectory: resolve('test/.coverage'),
|
||||
enabled: false,
|
||||
include: ['src/**/*.ts'],
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue