Skip to content

Commit

Permalink
Prevent error when fetch response has empty body
Browse files Browse the repository at this point in the history
When using the fetch API, if the server responds with a successful response and a content type of json, the body is parsed as JSON. However, if the body is empty, this causes a JSON parsing error.
  • Loading branch information
yjukaku committed Mar 16, 2022
1 parent c4eb37a commit fdf7a7d
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/browser/telemetry.js
Expand Up @@ -403,8 +403,10 @@ Instrumenter.prototype.instrumentNetwork = function() {
// Test to ensure body is a Promise, which it should always be.
if (typeof body.then === 'function') {
body.then(function (text) {
if (self.isJsonContentType(metadata.response_content_type)) {
if (text && self.isJsonContentType(metadata.response_content_type)) {
metadata.response.body = self.scrubJson(text);
} else {
metadata.response.body = text
}
});
} else {
Expand Down
62 changes: 62 additions & 0 deletions test/browser.rollbar.test.js
Expand Up @@ -1575,6 +1575,68 @@ describe('options.autoInstrument', function() {
})
});

it('should not fail if a fetch call responds with an empty body', function(done) {
var server = window.server;
stubResponse(server);
server.requests.length = 0;

window.fetchStub = sinon.stub(window, 'fetch');

var readableStream = new ReadableStream({
start(controller) {
controller.enqueue("");
controller.close();
}
});

window.fetch.returns(Promise.resolve(new Response(
readableStream,
{ status: 200, statusText: 'OK', headers: { 'content-type': 'application/json' }}
)));

var options = {
accessToken: 'POST_CLIENT_ITEM_TOKEN',
autoInstrument: {
log: false,
network: true,
networkResponseHeaders: true,
networkResponseBody: true,
networkRequestBody: true,
networkRequestHeaders: true
}
};
var rollbar = window.rollbar = new Rollbar(options);

var fetchHeaders = new Headers();
fetchHeaders.append('Content-Type', 'application/json');

const fetchInit = {
method: 'POST',
headers: fetchHeaders,
body: "{}"
};
var fetchRequest = new Request('https://example.com/xhr-test');
window.fetch(fetchRequest, fetchInit)
.then(function(response) {
try {
rollbar.log('test'); // generate a payload to inspect
server.respond();

expect(server.requests.length).to.eql(1);

var body = JSON.parse(server.requests[0].requestBody);
// Verify response headers capture
expect(body.data.body.telemetry[0].body.response.headers).to.eql({'content-type': 'application/json'});

rollbar.configure({ autoInstrument: false });
window.fetch.restore();
done();
} catch (e) {
done(e);
}
})
});

it('should add a diagnostic message when wrapConsole fails', function(done) {
var server = window.server;
stubResponse(server);
Expand Down

0 comments on commit fdf7a7d

Please sign in to comment.