From 1b9b34dd0b29c19acb818eec78d6e36ebb050498 Mon Sep 17 00:00:00 2001 From: JounQin Date: Mon, 29 Jan 2024 17:14:16 +0800 Subject: [PATCH 1/2] fix: only fallback to text on error --- src/index.ts | 2 +- src/utils.ts | 28 +++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index eb03cb3..b33660a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -97,7 +97,7 @@ export const createFetchApi = (fetch = globalThis.fetch) => { return response } throw Object.assign(new Error(response.statusText), { - data: extractDataFromResponse(response, type), + data: extractDataFromResponse(response, type, true), response, }) } diff --git a/src/utils.ts b/src/utils.ts index b79a078..7c5967a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -60,31 +60,38 @@ export const normalizeUrl = (url: string, query?: URLSearchParamsOptions) => { export async function extractDataFromResponse( res: Response, type: null, + fallback?: boolean, ): Promise export async function extractDataFromResponse( res: Response, type: 'arrayBuffer', + fallback?: boolean, ): Promise export async function extractDataFromResponse( res: Response, type: 'blob', + fallback?: boolean, ): Promise export async function extractDataFromResponse( res: Response, type: 'json', + fallback?: boolean, ): Promise export async function extractDataFromResponse( res: Response, type: 'text', + fallback?: boolean, ): Promise export async function extractDataFromResponse( res: Response, type: ResponseType, + fallback?: boolean, ): Promise // eslint-disable-next-line sonarjs/cognitive-complexity export async function extractDataFromResponse( res: Response, type: ResponseType, + fallback?: boolean, ) { let data: unknown if (type != null) { @@ -93,15 +100,26 @@ export async function extractDataFromResponse( // data could be empty text data = await res.clone().text() } catch {} - if (type === 'json' && (data = (data as string).trim())) { - try { - data = JSON.parse(data as string) - } catch {} + if (type === 'json') { + if ((data = (data as string).trim())) { + try { + data = JSON.parse(data as string) + } catch (err) { + if (!fallback) { + throw err + } + } + } else { + data = null + } } } else { try { data = await res.clone()[type]() - } catch { + } catch (err) { + if (!fallback) { + throw err + } data = await res.clone().text() } } From 512f640f3eb72a155bd2432366a7a024cc9dc34c Mon Sep 17 00:00:00 2001 From: JounQin Date: Mon, 29 Jan 2024 17:16:57 +0800 Subject: [PATCH 2/2] chore: update test case --- package.json | 4 ++-- test/utils.spec.ts | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 1622b3a..f6e113f 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,8 @@ "module": "./lib/index.js", "exports": { "types": "./lib/index.d.ts", - "import": "./lib/index.js", - "require": "./lib/index.cjs" + "require": "./lib/index.cjs", + "default": "./lib/index.js" }, "types": "./lib/index.d.ts", "files": [ diff --git a/test/utils.spec.ts b/test/utils.spec.ts index 89126db..8374094 100644 --- a/test/utils.spec.ts +++ b/test/utils.spec.ts @@ -43,7 +43,15 @@ test('extractDataFromResponse', async () => { expect(await extractDataFromResponse(new Response(), 'text')).toBe('') expect(await extractDataFromResponse(new Response(null), 'text')).toBe('') expect(await extractDataFromResponse(new Response('foo'), 'text')).toBe('foo') - expect(await extractDataFromResponse(new Response('foo'), 'json')).toBe('foo') + await expect(() => + extractDataFromResponse(new Response('foo'), 'json'), + ).rejects.toThrow( + // eslint-disable-next-line unicorn/better-regex, regexp/no-dupe-characters-character-class + /[SyntaxError: Unexpected token (('o', "foo" is not valid JSON)|(o in JSON at position 1))]/, + ) + expect(await extractDataFromResponse(new Response('foo'), 'json', true)).toBe( + 'foo', + ) expect( await extractDataFromResponse(new Response('{"foo":"bar"}'), 'json'), ).toEqual({ foo: 'bar' })