diff --git a/.changeset/late-donkeys-collect.md b/.changeset/late-donkeys-collect.md new file mode 100644 index 000000000..d4b2d5fd9 --- /dev/null +++ b/.changeset/late-donkeys-collect.md @@ -0,0 +1,5 @@ +--- +'@lion/ajax': patch +--- + +don't throw on non-JSON responses in fetchJson diff --git a/packages/ajax/src/Ajax.js b/packages/ajax/src/Ajax.js index 94f292482..f05ae5758 100644 --- a/packages/ajax/src/Ajax.js +++ b/packages/ajax/src/Ajax.js @@ -180,14 +180,19 @@ export class Ajax { responseText = responseText.substring(jsonPrefix.length); } - try { - return { - response, - body: JSON.parse(responseText), - }; - } catch (error) { - throw new Error(`Failed to parse response from ${response.url} as JSON.`); + /** @type {any} */ + let body = responseText; + if (response.headers.get('content-type')?.includes('application/json')) { + try { + body = JSON.parse(responseText); + } catch (error) { + throw new Error(`Failed to parse response from ${response.url} as JSON.`); + } + } else { + body = responseText; } + + return { response, body }; } /** diff --git a/packages/ajax/test/Ajax.test.js b/packages/ajax/test/Ajax.test.js index f9f84f608..3dcd661ef 100644 --- a/packages/ajax/test/Ajax.test.js +++ b/packages/ajax/test/Ajax.test.js @@ -159,6 +159,12 @@ describe('Ajax', () => { expect(response.response.headers.get('X-Custom-Header')).to.equal('y-custom-value'); }); + it('handles non-json responses', async () => { + fetchStub.returns(Promise.resolve(new Response('!@#$'))); + const response = await ajax.fetchJson('/foo'); + expect(response.body).to.eql('!@#$'); + }); + describe('given a request body', () => { it('encodes the request body as json', async () => { await ajax.fetchJson('/foo', { method: 'POST', body: { a: 1, b: 2 } }); @@ -176,14 +182,14 @@ describe('Ajax', () => { describe('given a json prefix', () => { it('strips json prefix from response before decoding', async () => { const localAjax = new Ajax({ jsonPrefix: '//.,!' }); - fetchStub.returns(Promise.resolve(new Response('//.,!{"a":1,"b":2}'))); + fetchStub.returns(Promise.resolve(new Response('//.,!{"a":1,"b":2}', responseInit()))); const response = await localAjax.fetchJson('/foo'); expect(response.body).to.eql({ a: 1, b: 2 }); }); }); it('throws on invalid JSON responses', async () => { - fetchStub.returns(Promise.resolve(new Response('invalid-json'))); + fetchStub.returns(Promise.resolve(new Response('invalid-json', responseInit()))); let thrown = false; try {