@@ -30,6 +30,85 @@ describe("window.onunhandledrejection", function() {
3030 } ) ;
3131 } ) ;
3232
33+ // something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents
34+ // to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
35+ // the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
36+ // see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
37+ // https://github.com/getsentry/sentry-javascript/issues/2380
38+ it ( "should capture PromiseRejectionEvent cast to CustomEvent with type unhandledrejection" , function ( ) {
39+ return runInSandbox ( sandbox , function ( ) {
40+ if ( supportsOnunhandledRejection ( ) ) {
41+ // this isn't how it happens in real life, in that the promise and reason
42+ // values come from an actual PromiseRejectionEvent, but it's enough to test
43+ // how the SDK handles the structure
44+ window . dispatchEvent (
45+ new CustomEvent ( "unhandledrejection" , {
46+ detail : {
47+ promise : new Promise ( ( ) => { } ) ,
48+ // we're testing with an error here but it could be anything - really
49+ // all we're testing is that it gets dug out correctly
50+ reason : new Error ( "test2" ) ,
51+ } ,
52+ } )
53+ ) ;
54+ Promise . reject ( ) ;
55+ } else {
56+ window . resolveTest ( { window : window } ) ;
57+ }
58+ } ) . then ( function ( summary ) {
59+ if ( summary . window . supportsOnunhandledRejection ( ) ) {
60+ assert . equal ( summary . events [ 0 ] . exception . values [ 0 ] . value , "test2" ) ;
61+ assert . equal ( summary . events [ 0 ] . exception . values [ 0 ] . type , "Error" ) ;
62+
63+ // Of course Safari had to screw up here...
64+ if ( ! / V e r s i o n \/ \d .+ S a f a r i \/ \d / . test ( window . navigator . userAgent ) ) {
65+ assert . isAtLeast (
66+ summary . events [ 0 ] . exception . values [ 0 ] . stacktrace . frames . length ,
67+ 1
68+ ) ;
69+ }
70+ assert . equal (
71+ summary . events [ 0 ] . exception . values [ 0 ] . mechanism . handled ,
72+ false
73+ ) ;
74+ assert . equal (
75+ summary . events [ 0 ] . exception . values [ 0 ] . mechanism . type ,
76+ "onunhandledrejection"
77+ ) ;
78+ }
79+ } ) ;
80+ } ) ;
81+
82+ // there's no evidence that this actually happens, but it could, and our code correctly
83+ // handles it, so might as well prevent future regression on that score
84+ it ( "should capture a random Event with type unhandledrejection" , function ( ) {
85+ return runInSandbox ( sandbox , function ( ) {
86+ if ( supportsOnunhandledRejection ( ) ) {
87+ window . dispatchEvent ( new Event ( "unhandledrejection" ) ) ;
88+ Promise . reject ( ) ;
89+ } else {
90+ window . resolveTest ( { window : window } ) ;
91+ }
92+ } ) . then ( function ( summary ) {
93+ if ( summary . window . supportsOnunhandledRejection ( ) ) {
94+ // non-error rejections don't provide stacktraces so we can skip that assertion
95+ assert . equal (
96+ summary . events [ 0 ] . exception . values [ 0 ] . value ,
97+ "Non-Error promise rejection captured with keys: currentTarget, isTrusted, target, type"
98+ ) ;
99+ assert . equal ( summary . events [ 0 ] . exception . values [ 0 ] . type , "Event" ) ;
100+ assert . equal (
101+ summary . events [ 0 ] . exception . values [ 0 ] . mechanism . handled ,
102+ false
103+ ) ;
104+ assert . equal (
105+ summary . events [ 0 ] . exception . values [ 0 ] . mechanism . type ,
106+ "onunhandledrejection"
107+ ) ;
108+ }
109+ } ) ;
110+ } ) ;
111+
33112 it ( "should capture unhandledrejection with a string" , function ( ) {
34113 return runInSandbox ( sandbox , function ( ) {
35114 if ( supportsOnunhandledRejection ( ) ) {
@@ -39,7 +118,7 @@ describe("window.onunhandledrejection", function() {
39118 }
40119 } ) . then ( function ( summary ) {
41120 if ( summary . window . supportsOnunhandledRejection ( ) ) {
42- // non-error rejections doesnt provide stacktraces so we can skip the assertion
121+ // non-error rejections don't provide stacktraces so we can skip that assertion
43122 assert . equal (
44123 summary . events [ 0 ] . exception . values [ 0 ] . value ,
45124 "Non-Error promise rejection captured with value: test"
@@ -69,7 +148,7 @@ describe("window.onunhandledrejection", function() {
69148 }
70149 } ) . then ( function ( summary ) {
71150 if ( summary . window . supportsOnunhandledRejection ( ) ) {
72- // non-error rejections doesnt provide stacktraces so we can skip the assertion
151+ // non-error rejections don't provide stacktraces so we can skip that assertion
73152 assert . equal ( summary . events [ 0 ] . exception . values [ 0 ] . value . length , 253 ) ;
74153 assert . include (
75154 summary . events [ 0 ] . exception . values [ 0 ] . value ,
@@ -100,7 +179,7 @@ describe("window.onunhandledrejection", function() {
100179 }
101180 } ) . then ( function ( summary ) {
102181 if ( summary . window . supportsOnunhandledRejection ( ) ) {
103- // non-error rejections doesnt provide stacktraces so we can skip the assertion
182+ // non-error rejections don't provide stacktraces so we can skip that assertion
104183 assert . equal (
105184 summary . events [ 0 ] . exception . values [ 0 ] . value ,
106185 "Non-Error promise rejection captured with keys: a, b, c"
@@ -137,7 +216,7 @@ describe("window.onunhandledrejection", function() {
137216 }
138217 } ) . then ( function ( summary ) {
139218 if ( summary . window . supportsOnunhandledRejection ( ) ) {
140- // non-error rejections doesnt provide stacktraces so we can skip the assertion
219+ // non-error rejections don't provide stacktraces so we can skip that assertion
141220 assert . equal (
142221 summary . events [ 0 ] . exception . values [ 0 ] . value ,
143222 "Non-Error promise rejection captured with keys: a, b, c, d, e"
@@ -167,7 +246,7 @@ describe("window.onunhandledrejection", function() {
167246 }
168247 } ) . then ( function ( summary ) {
169248 if ( summary . window . supportsOnunhandledRejection ( ) ) {
170- // non-error rejections doesnt provide stacktraces so we can skip the assertion
249+ // non-error rejections don't provide stacktraces so we can skip that assertion
171250 assert . equal (
172251 summary . events [ 0 ] . exception . values [ 0 ] . value ,
173252 "Non-Error promise rejection captured with value: 1337"
@@ -197,7 +276,7 @@ describe("window.onunhandledrejection", function() {
197276 }
198277 } ) . then ( function ( summary ) {
199278 if ( summary . window . supportsOnunhandledRejection ( ) ) {
200- // non-error rejections doesnt provide stacktraces so we can skip the assertion
279+ // non-error rejections don't provide stacktraces so we can skip that assertion
201280 assert . equal (
202281 summary . events [ 0 ] . exception . values [ 0 ] . value ,
203282 "Non-Error promise rejection captured with value: null"
@@ -227,7 +306,7 @@ describe("window.onunhandledrejection", function() {
227306 }
228307 } ) . then ( function ( summary ) {
229308 if ( summary . window . supportsOnunhandledRejection ( ) ) {
230- // non-error rejections doesnt provide stacktraces so we can skip the assertion
309+ // non-error rejections don't provide stacktraces so we can skip that assertion
231310 assert . equal (
232311 summary . events [ 0 ] . exception . values [ 0 ] . value ,
233312 "Non-Error promise rejection captured with value: undefined"
0 commit comments