Skip to content

Commit db16c0c

Browse files
committed
Record fetch requests in breadcrumb
1 parent 9ede556 commit db16c0c

File tree

5 files changed

+87
-2
lines changed

5 files changed

+87
-2
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"bundle-collapser": "^1.2.1",
2323
"chai": "2.3.0",
2424
"derequire": "2.0.3",
25+
"es6-promise": "^4.0.5",
2526
"grunt": "^0.4.5",
2627
"grunt-browserify": "^4.0.1",
2728
"grunt-cli": "^0.1.13",
@@ -43,7 +44,8 @@
4344
"proxyquireify": "^3.0.2",
4445
"sinon": "1.7.3",
4546
"through2": "^2.0.0",
46-
"typescript": "^1.8.10"
47+
"typescript": "^1.8.10",
48+
"whatwg-fetch": "^1.0.0"
4749
},
4850
"keywords": [
4951
"exceptions",

src/raven.js

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ Raven.prototype = {
128128
xhr: true,
129129
console: true,
130130
dom: true,
131-
location: true
131+
location: true,
132+
fetch: true
132133
};
133134

134135
var autoBreadcrumbs = globalOptions.autoBreadcrumbs;
@@ -971,6 +972,43 @@ Raven.prototype = {
971972
}, wrappedBuiltIns);
972973
}
973974

975+
if (autoBreadcrumbs.fetch && 'fetch' in _window) {
976+
fill(_window, 'fetch', function(origFetch) {
977+
return function (fn, t) { // preserve arity
978+
// Make a copy of the arguments to prevent deoptimization
979+
// https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
980+
var args = new Array(arguments.length);
981+
for(var i = 0; i < args.length; ++i) {
982+
args[i] = arguments[i];
983+
}
984+
985+
var method = 'GET';
986+
987+
if (args[1] && args[1].method) {
988+
method = args[1].method;
989+
}
990+
991+
var fetchData = {
992+
method: method,
993+
url: args[0],
994+
status_code: null
995+
};
996+
997+
self.captureBreadcrumb({
998+
type: 'http',
999+
category: 'fetch',
1000+
data: fetchData
1001+
});
1002+
1003+
return origFetch.apply(this, args).then(function (response) {
1004+
fetchData.status_code = response.status;
1005+
1006+
return response;
1007+
});
1008+
};
1009+
}, wrappedBuiltIns);
1010+
}
1011+
9741012
// Capture breadcrumbs from any click that is unhandled / bubbled up all the way
9751013
// to the document. Do this before we instrument addEventListener.
9761014
if (autoBreadcrumbs.dom && this._hasDocument) {

test/integration/frame.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<head>
44
<meta charset="utf-8">
55
<title></title>
6+
<script src="../../node_modules/es6-promise/dist/es6-promise.auto.js"></script>
7+
<script src="../../node_modules/whatwg-fetch/fetch.js"></script>
68
<script>
79
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
810
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating

test/integration/test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ describe('integration', function () {
405405
assert.equal(breadcrumbs.length, 1);
406406

407407
assert.equal(breadcrumbs[0].type, 'http');
408+
assert.equal(breadcrumbs[0].category, 'xhr');
408409
assert.equal(breadcrumbs[0].data.method, 'GET');
409410
// NOTE: not checking status code because we seem to get
410411
// statusCode 0/undefined from Phantom when fetching
@@ -441,6 +442,46 @@ describe('integration', function () {
441442
);
442443
});
443444

445+
it('should record a fetch request', function (done) {
446+
var iframe = this.iframe;
447+
448+
iframeExecute(iframe, done,
449+
function () {
450+
// some browsers trigger onpopstate for load / reset breadcrumb state
451+
Raven._breadcrumbs = [];
452+
453+
fetch('/test/integration/example.json').then(function () {
454+
setTimeout(done);
455+
}, function () {
456+
setTimeout(done);
457+
});
458+
},
459+
function () {
460+
var Raven = iframe.contentWindow.Raven,
461+
breadcrumbs = Raven._breadcrumbs;
462+
463+
if ('fetch' in window) {
464+
assert.equal(breadcrumbs.length, 1);
465+
466+
assert.equal(breadcrumbs[0].type, 'http');
467+
assert.equal(breadcrumbs[0].category, 'fetch');
468+
assert.equal(breadcrumbs[0].data.method, 'GET');
469+
} else {
470+
// otherwise we use a fetch polyfill based on xhr
471+
assert.equal(breadcrumbs.length, 2);
472+
473+
assert.equal(breadcrumbs[0].type, 'http');
474+
assert.equal(breadcrumbs[0].category, 'fetch');
475+
assert.equal(breadcrumbs[0].data.method, 'GET');
476+
477+
assert.equal(breadcrumbs[1].type, 'http');
478+
assert.equal(breadcrumbs[1].category, 'xhr');
479+
assert.equal(breadcrumbs[1].data.method, 'GET');
480+
}
481+
}
482+
);
483+
});
484+
444485
it('should record a mouse click on element WITH click handler present', function (done) {
445486
var iframe = this.iframe;
446487

test/raven.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,7 @@ describe('Raven (public API)', function() {
16161616
xhr: true,
16171617
console: true,
16181618
dom: true,
1619+
fetch: true,
16191620
location: true
16201621
});
16211622
});
@@ -1637,6 +1638,7 @@ describe('Raven (public API)', function() {
16371638
xhr: true,
16381639
console: true,
16391640
dom: true,
1641+
fetch: true,
16401642
location: false /* ! */
16411643
});
16421644
});

0 commit comments

Comments
 (0)