Skip to content

Commit

Permalink
fix: only fallback to text on error (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
JounQin authored Jan 29, 2024
1 parent dba61f1 commit 5e1cd70
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 9 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})
}
Expand Down
28 changes: 23 additions & 5 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,31 +60,38 @@ export const normalizeUrl = (url: string, query?: URLSearchParamsOptions) => {
export async function extractDataFromResponse(
res: Response,
type: null,
fallback?: boolean,
): Promise<Response>
export async function extractDataFromResponse(
res: Response,
type: 'arrayBuffer',
fallback?: boolean,
): Promise<ArrayBuffer>
export async function extractDataFromResponse(
res: Response,
type: 'blob',
fallback?: boolean,
): Promise<Blob>
export async function extractDataFromResponse<T>(
res: Response,
type: 'json',
fallback?: boolean,
): Promise<T>
export async function extractDataFromResponse(
res: Response,
type: 'text',
fallback?: boolean,
): Promise<string>
export async function extractDataFromResponse(
res: Response,
type: ResponseType,
fallback?: boolean,
): Promise<unknown>
// eslint-disable-next-line sonarjs/cognitive-complexity
export async function extractDataFromResponse(
res: Response,
type: ResponseType,
fallback?: boolean,
) {
let data: unknown
if (type != null) {
Expand All @@ -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()
}
}
Expand Down
10 changes: 9 additions & 1 deletion test/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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' })
Expand Down

0 comments on commit 5e1cd70

Please sign in to comment.