feat: 适配器异常处理成响应异常

pull/41/head
zjx0905 2023-04-11 13:13:45 +08:00
parent adb9dbe88f
commit be17ba7e68
7 changed files with 102 additions and 36 deletions

2
.gitignore vendored
View File

@ -19,7 +19,7 @@ lib/
*.test.js *.test.js
*.test.d.ts *.test.d.ts
*.test.js.map *.test.js.map
coverage .coverage
# eslint # eslint
.eslintcache .eslintcache

View File

@ -2,6 +2,7 @@ import {
isEmptyArray, isEmptyArray,
isFunction, isFunction,
isPlainObject, isPlainObject,
isString,
isUndefined, isUndefined,
} from './helpers/isTypes'; } from './helpers/isTypes';
import { assert } from './helpers/error'; import { assert } from './helpers/error';
@ -57,6 +58,19 @@ export interface AxiosAdapterResponseError extends AnyObject {
* *
*/ */
headers: AnyObject; headers: AnyObject;
/**
*
*/
data?: {
/**
*
*/
errMsg: string;
/**
* Errno
*/
errno: number;
};
} }
export interface AxiosAdapterRequestConfig extends AnyObject { export interface AxiosAdapterRequestConfig extends AnyObject {
@ -253,22 +267,25 @@ export function createAdapter(platform: AxiosPlatform) {
return download(options); return download(options);
} }
function transformResult(result: AnyObject): void { function transformResponse(response: AnyObject): void {
result.status = response.status = response.status ?? response.statusCode;
result.status ?? response.statusText = 'OK';
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;
if (result.statusCode) delete result.statusCode; if (isUndefined(response.status)) {
if (result.errMsg) delete result.errMsg; response.status = 400;
if (result.header) delete result.header; 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( function transformOptions(
@ -278,11 +295,11 @@ export function createAdapter(platform: AxiosPlatform) {
...config, ...config,
header: config.headers, header: config.headers,
success(response): void { success(response): void {
transformResult(response); transformResponse(response);
config.success(response); config.success(response);
}, },
fail(error: AxiosAdapterResponseError): void { fail(error: AxiosAdapterResponseError): void {
transformResult(error); transformResponse(error);
config.fail(error); config.fail(error);
}, },
}; };
@ -297,9 +314,16 @@ export function createAdapter(platform: AxiosPlatform) {
response.apFilePath, response.apFilePath,
}; };
if (response.tempFilePath) delete response.tempFilePath; cleanResponse(response, ['tempFilePath', 'apFilePath', 'filePath']);
if (response.apFilePath) delete response.apFilePath; }
if (response.filePath) delete response.filePath;
/**
* response key
*/
function cleanResponse(response: AnyObject, keys: string[]) {
for (const key of keys) {
if (key in response) delete response[key];
}
} }
return adapter; return adapter;

View File

@ -186,7 +186,7 @@ export interface AxiosResponse<
export interface AxiosResponseError extends AxiosAdapterResponseError { export interface AxiosResponseError extends AxiosAdapterResponseError {
/** /**
* fail *
*/ */
isFail: true; isFail: true;
/** /**

View File

@ -4,6 +4,7 @@ import {
AxiosAdapterRequestMethod, AxiosAdapterRequestMethod,
AxiosAdapterResponse, AxiosAdapterResponse,
AxiosAdapterResponseError, AxiosAdapterResponseError,
AxiosAdapterTask,
} from '../adapter'; } from '../adapter';
import { import {
AxiosProgressCallback, AxiosProgressCallback,
@ -49,7 +50,16 @@ export function request(config: AxiosRequestConfig) {
fail, fail,
}; };
const adapterTask = adapter!(adapterConfig); let adapterTask: AxiosAdapterTask;
try {
adapterTask = adapter!(adapterConfig);
} catch {
fail({
status: 400,
statusText: 'Bad Adapter',
headers: {},
});
}
function success(_: AxiosAdapterResponse): void { function success(_: AxiosAdapterResponse): void {
const response = _ as AxiosResponse; const response = _ as AxiosResponse;

View File

@ -253,12 +253,14 @@ describe('src/adapter.ts', () => {
}; };
const p2 = { const p2 = {
...p1, ...p1,
request: vi.fn(({ fail }) => fail({ data: { result: null } })), request: vi.fn(({ fail }) =>
fail({ status: 500, data: { result: null } }),
),
}; };
const p3 = { const p3 = {
...p1, ...p1,
request: vi.fn(({ fail }) => request: vi.fn(({ fail }) =>
fail({ statusCode: 500, header: {}, errMsg: 'request:fail' }), fail({ errMsg: 'request:fail', errno: 1000 }),
), ),
}; };
const c1 = { const c1 = {
@ -269,9 +271,9 @@ describe('src/adapter.ts', () => {
fail: (response: any) => { fail: (response: any) => {
expect(response).toMatchInlineSnapshot(` expect(response).toMatchInlineSnapshot(`
{ {
"headers": undefined, "headers": {},
"status": 400, "status": 400,
"statusText": "Bad Adapter", "statusText": "Fail Adapter",
} }
`); `);
}, },
@ -284,8 +286,8 @@ describe('src/adapter.ts', () => {
"data": { "data": {
"result": null, "result": null,
}, },
"headers": undefined, "headers": {},
"status": 200, "status": 500,
"statusText": "OK", "statusText": "OK",
} }
`); `);
@ -296,9 +298,13 @@ describe('src/adapter.ts', () => {
fail: (response: any) => { fail: (response: any) => {
expect(response).toMatchInlineSnapshot(` expect(response).toMatchInlineSnapshot(`
{ {
"data": {
"errMsg": "request:fail",
"errno": 1000,
},
"headers": {}, "headers": {},
"status": 500, "status": 400,
"statusText": "request:fail", "statusText": "Fail Adapter",
} }
`); `);
}, },

View File

@ -37,16 +37,42 @@ describe('src/core/dispatchRequest.ts', () => {
).not.toThrowError(); ).not.toThrowError();
}); });
test('坏的适配器', () => { test('坏的适配器应该抛出异常', () => {
expect(() => expect(
dispatchRequest({ dispatchRequest({
adapter: () => { adapter: () => {
throw 'bad adapter'; throw 'bad adapter';
}, },
url: '/', url: '/',
method: 'get', method: 'get',
}), }).catch((e) => ({ ...e })),
).toMatchInlineSnapshot('[Function]'); ).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', () => { test('应该支持转换 URL', () => {

View File

@ -10,7 +10,7 @@ export default defineConfig({
}, },
coverage: { coverage: {
provider: 'istanbul', provider: 'istanbul',
reportsDirectory: resolve('test/coverage'), reportsDirectory: resolve('test/.coverage'),
enabled: false, enabled: false,
include: ['src/**/*.ts'], include: ['src/**/*.ts'],
}, },