Skip to content

Commit 56f075a

Browse files
authored
fix: Fallback to <anonymous> handler name in mechanism (#1359)
* fix: Fallback to <anonymous> handler name in mechanism * fix: Correct order of default overrides for ex mechanisms * test: Integration tests for ex mechanisms
1 parent 66c7226 commit 56f075a

File tree

2 files changed

+134
-61
lines changed

2 files changed

+134
-61
lines changed

packages/raven-js/src/raven.js

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,7 @@ Raven.prototype = {
11121112
{
11131113
mechanism: {
11141114
type: 'instrument',
1115-
data: {function: orig.name}
1115+
data: {function: orig.name || '<anonymous>'}
11161116
}
11171117
},
11181118
originalCallback
@@ -1147,7 +1147,11 @@ Raven.prototype = {
11471147
{
11481148
mechanism: {
11491149
type: 'instrument',
1150-
data: {target: global, function: 'handleEvent', handler: fn.name}
1150+
data: {
1151+
target: global,
1152+
function: 'handleEvent',
1153+
handler: (fn && fn.name) || '<anonymous>'
1154+
}
11511155
}
11521156
},
11531157
fn.handleEvent
@@ -1198,7 +1202,7 @@ Raven.prototype = {
11981202
data: {
11991203
target: global,
12001204
function: 'addEventListener',
1201-
handler: fn.name
1205+
handler: (fn && fn.name) || '<anonymous>'
12021206
}
12031207
}
12041208
},
@@ -1243,7 +1247,10 @@ Raven.prototype = {
12431247
{
12441248
mechanism: {
12451249
type: 'instrument',
1246-
data: {function: 'requestAnimationFrame', handler: orig.name}
1250+
data: {
1251+
function: 'requestAnimationFrame',
1252+
handler: (orig && orig.name) || '<anonymous>'
1253+
}
12471254
}
12481255
},
12491256
cb
@@ -1315,7 +1322,7 @@ Raven.prototype = {
13151322
{
13161323
mechanism: {
13171324
type: 'instrument',
1318-
data: {function: prop, handler: orig.name}
1325+
data: {function: prop, handler: (orig && orig.name) || '<anonymous>'}
13191326
}
13201327
},
13211328
orig
@@ -1390,7 +1397,7 @@ Raven.prototype = {
13901397
type: 'instrument',
13911398
data: {
13921399
function: 'onreadystatechange',
1393-
handler: orig.name
1400+
handler: (orig && orig.name) || '<anonymous>'
13941401
}
13951402
}
13961403
},
@@ -1774,10 +1781,13 @@ Raven.prototype = {
17741781
delete data.mechanism;
17751782
}
17761783

1777-
data.exception.mechanism = objectMerge(data.exception.mechanism || {}, {
1778-
type: 'generic',
1779-
handled: true
1780-
});
1784+
data.exception.mechanism = objectMerge(
1785+
{
1786+
type: 'generic',
1787+
handled: true
1788+
},
1789+
data.exception.mechanism || {}
1790+
);
17811791

17821792
// Fire away!
17831793
this._send(data);

packages/raven-js/test/integration/test.js

Lines changed: 114 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,7 @@ describe('integration', function() {
9494
);
9595
});
9696

97-
it('should generate a synthetic trace for captureException w/ non-errors', function(
98-
done
99-
) {
97+
it('should generate a synthetic trace for captureException w/ non-errors', function(done) {
10098
var iframe = this.iframe;
10199
iframeExecute(
102100
iframe,
@@ -114,9 +112,7 @@ describe('integration', function() {
114112
);
115113
});
116114

117-
it('should capture an Error object passed to Raven.captureException w/ maxMessageLength set (#647)', function(
118-
done
119-
) {
115+
it('should capture an Error object passed to Raven.captureException w/ maxMessageLength set (#647)', function(done) {
120116
var iframe = this.iframe;
121117
iframeExecute(
122118
iframe,
@@ -185,9 +181,7 @@ describe('integration', function() {
185181
);
186182
});
187183

188-
it('should not reject back-to-back errors with different stack traces', function(
189-
done
190-
) {
184+
it('should not reject back-to-back errors with different stack traces', function(done) {
191185
var iframe = this.iframe;
192186
iframeExecute(
193187
iframe,
@@ -236,9 +230,7 @@ describe('integration', function() {
236230
);
237231
});
238232

239-
it('should reject duplicate, back-to-back messages from captureMessage', function(
240-
done
241-
) {
233+
it('should reject duplicate, back-to-back messages from captureMessage', function(done) {
242234
var iframe = this.iframe;
243235
iframeExecute(
244236
iframe,
@@ -435,9 +427,7 @@ describe('integration', function() {
435427
);
436428
});
437429

438-
it('should catch an exception already caught [but rethrown] via Raven.captureException', function(
439-
done
440-
) {
430+
it('should catch an exception already caught [but rethrown] via Raven.captureException', function(done) {
441431
// unlike Raven.wrap which ALWAYS re-throws, we don't know if the user will
442432
// re-throw an exception passed to Raven.captureException, and so we cannot
443433
// automatically suppress the next error caught through window.onerror
@@ -493,9 +483,7 @@ describe('integration', function() {
493483
);
494484
});
495485

496-
it('should transparently remove event listeners from wrapped functions', function(
497-
done
498-
) {
486+
it('should transparently remove event listeners from wrapped functions', function(done) {
499487
var iframe = this.iframe;
500488

501489
iframeExecute(
@@ -585,9 +573,7 @@ describe('integration', function() {
585573
);
586574
});
587575

588-
it('should capture exceptions from XMLHttpRequest event handlers (e.g. onreadystatechange)', function(
589-
done
590-
) {
576+
it('should capture exceptions from XMLHttpRequest event handlers (e.g. onreadystatechange)', function(done) {
591577
var iframe = this.iframe;
592578

593579
iframeExecute(
@@ -618,6 +604,103 @@ describe('integration', function() {
618604
}
619605
);
620606
});
607+
608+
it("should capture built-in's mechanism type as instrument", function(done) {
609+
var iframe = this.iframe;
610+
611+
iframeExecute(
612+
iframe,
613+
done,
614+
function() {
615+
setTimeout(function() {
616+
setTimeout(done);
617+
foo();
618+
}, 10);
619+
},
620+
function() {
621+
var ravenData = iframe.contentWindow.ravenData[0];
622+
assert.deepEqual(ravenData.exception.mechanism, {
623+
type: 'instrument',
624+
handled: true,
625+
data: {function: 'setTimeout'}
626+
});
627+
}
628+
);
629+
});
630+
631+
it("should capture built-in's handlers fn name in mechanism data", function(done) {
632+
var iframe = this.iframe;
633+
634+
iframeExecute(
635+
iframe,
636+
done,
637+
function() {
638+
setTimeout(done);
639+
640+
var div = document.createElement('div');
641+
document.body.appendChild(div);
642+
div.addEventListener(
643+
'click',
644+
function namedFunction() {
645+
foo();
646+
},
647+
false
648+
);
649+
650+
var click = new MouseEvent('click');
651+
div.dispatchEvent(click);
652+
},
653+
function() {
654+
var ravenData = iframe.contentWindow.ravenData[0];
655+
assert.deepEqual(ravenData.exception.mechanism, {
656+
type: 'instrument',
657+
handled: true,
658+
data: {
659+
function: 'addEventListener',
660+
handler: 'namedFunction',
661+
target: 'EventTarget'
662+
}
663+
});
664+
}
665+
);
666+
});
667+
668+
it('should fallback to <anonymous> fn name in mechanism data if one is unavailable', function(done) {
669+
var iframe = this.iframe;
670+
671+
iframeExecute(
672+
iframe,
673+
done,
674+
function() {
675+
setTimeout(done);
676+
677+
var div = document.createElement('div');
678+
document.body.appendChild(div);
679+
div.addEventListener(
680+
'click',
681+
function() {
682+
foo();
683+
},
684+
false
685+
);
686+
687+
var click = new MouseEvent('click');
688+
div.dispatchEvent(click);
689+
},
690+
function() {
691+
var ravenData = iframe.contentWindow.ravenData[0];
692+
assert.deepEqual(ravenData.exception.mechanism, {
693+
type: 'instrument',
694+
handled: true,
695+
data: {
696+
function: 'addEventListener',
697+
handler: '<anonymous>',
698+
target: 'EventTarget'
699+
}
700+
});
701+
}
702+
);
703+
});
621704
});
622705

623706
describe('breadcrumbs', function() {
@@ -689,9 +772,7 @@ describe('integration', function() {
689772
);
690773
});
691774

692-
it('should NOT denote XMLHttpRequests to the Sentry store endpoint as requiring breadcrumb capture', function(
693-
done
694-
) {
775+
it('should NOT denote XMLHttpRequests to the Sentry store endpoint as requiring breadcrumb capture', function(done) {
695776
var iframe = this.iframe;
696777
iframeExecute(
697778
iframe,
@@ -762,9 +843,7 @@ describe('integration', function() {
762843
);
763844
});
764845

765-
it('should record a fetch request with Request obj instead of URL string', function(
766-
done
767-
) {
846+
it('should record a fetch request with Request obj instead of URL string', function(done) {
768847
var iframe = this.iframe;
769848

770849
iframeExecute(
@@ -864,9 +943,7 @@ describe('integration', function() {
864943
);
865944
});
866945

867-
it('should record a mouse click on element WITH click handler present', function(
868-
done
869-
) {
946+
it('should record a mouse click on element WITH click handler present', function(done) {
870947
var iframe = this.iframe;
871948

872949
iframeExecute(
@@ -906,9 +983,7 @@ describe('integration', function() {
906983
);
907984
});
908985

909-
it('should record a mouse click on element WITHOUT click handler present', function(
910-
done
911-
) {
986+
it('should record a mouse click on element WITHOUT click handler present', function(done) {
912987
var iframe = this.iframe;
913988

914989
iframeExecute(
@@ -940,9 +1015,7 @@ describe('integration', function() {
9401015
);
9411016
});
9421017

943-
it('should only record a SINGLE mouse click for a tree of elements with event listeners', function(
944-
done
945-
) {
1018+
it('should only record a SINGLE mouse click for a tree of elements with event listeners', function(done) {
9461019
var iframe = this.iframe;
9471020

9481021
iframeExecute(
@@ -982,9 +1055,7 @@ describe('integration', function() {
9821055
);
9831056
});
9841057

985-
it('should bail out if accessing the `type` and `target` properties of an event throw an exception', function(
986-
done
987-
) {
1058+
it('should bail out if accessing the `type` and `target` properties of an event throw an exception', function(done) {
9881059
// see: https://github.com/getsentry/raven-js/issues/768
9891060
var iframe = this.iframe;
9901061

@@ -1019,9 +1090,7 @@ describe('integration', function() {
10191090
);
10201091
});
10211092

1022-
it('should record consecutive keypress events into a single "input" breadcrumb', function(
1023-
done
1024-
) {
1093+
it('should record consecutive keypress events into a single "input" breadcrumb', function(done) {
10251094
var iframe = this.iframe;
10261095

10271096
iframeExecute(
@@ -1092,9 +1161,7 @@ describe('integration', function() {
10921161
);
10931162
});
10941163

1095-
it('should flush keypress breadcrumb when input event occurs immediately after', function(
1096-
done
1097-
) {
1164+
it('should flush keypress breadcrumb when input event occurs immediately after', function(done) {
10981165
var iframe = this.iframe;
10991166

11001167
iframeExecute(
@@ -1146,9 +1213,7 @@ describe('integration', function() {
11461213
);
11471214
});
11481215

1149-
it('should record consecutive keypress events in a contenteditable into a single "input" breadcrumb', function(
1150-
done
1151-
) {
1216+
it('should record consecutive keypress events in a contenteditable into a single "input" breadcrumb', function(done) {
11521217
var iframe = this.iframe;
11531218

11541219
iframeExecute(
@@ -1183,9 +1248,7 @@ describe('integration', function() {
11831248
);
11841249
});
11851250

1186-
it('should record history.[pushState|replaceState] changes as navigation breadcrumbs', function(
1187-
done
1188-
) {
1251+
it('should record history.[pushState|replaceState] changes as navigation breadcrumbs', function(done) {
11891252
var iframe = this.iframe;
11901253

11911254
iframeExecute(

0 commit comments

Comments
 (0)