Skip to content

Commit 04ab9f1

Browse files
alxhubtbosch
authored andcommitted
fix(common): attempt to JSON.parse errors for JSON responses (#19773)
PR Close #19773
1 parent 25cbc98 commit 04ab9f1

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

packages/common/http/src/xhr.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,14 @@ export class HttpXhrBackend implements HttpBackend {
191191
// The parse error contains the text of the body that failed to parse.
192192
body = { error, text: body } as HttpJsonParseError;
193193
}
194+
} else if (!ok && req.responseType === 'json' && typeof body === 'string') {
195+
try {
196+
// Attempt to parse the body as JSON.
197+
body = JSON.parse(body);
198+
} catch (error) {
199+
// Cannot be certain that the body was meant to be parsed as JSON.
200+
// Leave the body as a string.
201+
}
194202
}
195203

196204
if (ok) {

packages/common/http/test/xhr_spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {MockXhrFactory} from './xhr_mock';
1717

1818
function trackEvents(obs: Observable<HttpEvent<any>>): HttpEvent<any>[] {
1919
const events: HttpEvent<any>[] = [];
20-
obs.subscribe(event => events.push(event));
20+
obs.subscribe(event => events.push(event), err => events.push(err));
2121
return events;
2222
}
2323

@@ -92,6 +92,13 @@ export function main() {
9292
const res = events[1] as HttpResponse<{data: string}>;
9393
expect(res.body !.data).toBe('some data');
9494
});
95+
it('handles a json error response', () => {
96+
const events = trackEvents(backend.handle(TEST_POST.clone({responseType: 'json'})));
97+
factory.mock.mockFlush(500, 'Error', JSON.stringify({data: 'some data'}));
98+
expect(events.length).toBe(2);
99+
const res = events[1] as any as HttpErrorResponse;
100+
expect(res.error !.data).toBe('some data');
101+
});
95102
it('handles a json string response', () => {
96103
const events = trackEvents(backend.handle(TEST_POST.clone({responseType: 'json'})));
97104
expect(factory.mock.responseType).toEqual('text');

0 commit comments

Comments
 (0)