From be17ba7e6881699aeb74b45c8b4b084e1e53a777 Mon Sep 17 00:00:00 2001 From: zjx0905 <954270063@qq.com> Date: Tue, 11 Apr 2023 13:13:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=80=82=E9=85=8D=E5=99=A8=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=A4=84=E7=90=86=E6=88=90=E5=93=8D=E5=BA=94=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- src/adapter.ts | 64 +++++++++++++++++++++---------- src/core/Axios.ts | 2 +- src/core/request.ts | 12 +++++- test/adapter.test.ts | 22 +++++++---- test/core/dispatchRequest.test.ts | 34 ++++++++++++++-- vitest.config.ts | 2 +- 7 files changed, 102 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index 23fd849..29f1edf 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,7 @@ lib/ *.test.js *.test.d.ts *.test.js.map -coverage +.coverage # eslint .eslintcache diff --git a/src/adapter.ts b/src/adapter.ts index aaacef9..ac3ccb4 100644 --- a/src/adapter.ts +++ b/src/adapter.ts @@ -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; diff --git a/src/core/Axios.ts b/src/core/Axios.ts index 1d519a8..e9d35e3 100644 --- a/src/core/Axios.ts +++ b/src/core/Axios.ts @@ -186,7 +186,7 @@ export interface AxiosResponse< export interface AxiosResponseError extends AxiosAdapterResponseError { /** - * 原生接口 fail 回调产生的响应错误 + * 失败的请求,指没能够成功响应的请求 */ isFail: true; /** diff --git a/src/core/request.ts b/src/core/request.ts index 58bd1ae..2ba3893 100644 --- a/src/core/request.ts +++ b/src/core/request.ts @@ -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; diff --git a/test/adapter.test.ts b/test/adapter.test.ts index 1a20f5a..7216abd 100644 --- a/test/adapter.test.ts +++ b/test/adapter.test.ts @@ -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", } `); }, diff --git a/test/core/dispatchRequest.test.ts b/test/core/dispatchRequest.test.ts index 74ba0c8..676cfd7 100644 --- a/test/core/dispatchRequest.test.ts +++ b/test/core/dispatchRequest.test.ts @@ -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', () => { diff --git a/vitest.config.ts b/vitest.config.ts index ebe184a..3f23905 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -10,7 +10,7 @@ export default defineConfig({ }, coverage: { provider: 'istanbul', - reportsDirectory: resolve('test/coverage'), + reportsDirectory: resolve('test/.coverage'), enabled: false, include: ['src/**/*.ts'], },