Skip to content

Commit bd0649c

Browse files
authored
fix(integrations): Treat specific CustomEvents as promise rejections (getsentry#2429)
1 parent 3d19778 commit bd0649c

File tree

4 files changed

+22
-6
lines changed

4 files changed

+22
-6
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- [browser] fix: Handle PromiseRejectionEvent-like CustomEvents
6+
57
## 5.12.3
68

79
- [apm] fix: Remove undefined keys from trace.context

packages/browser/src/integrations/globalhandlers.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,22 @@ export class GlobalHandlers implements Integration {
138138

139139
this._global.onunhandledrejection = function(e: any): boolean {
140140
let error = e;
141+
142+
// dig the object of the rejection out of known event types
141143
try {
142-
error = e && 'reason' in e ? e.reason : e;
144+
// PromiseRejectionEvents store the object of the rejection under 'reason'
145+
// see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
146+
if ('reason' in e) {
147+
error = e.reason;
148+
}
149+
// something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents
150+
// to CustomEvents, moving the `promise` and `reason` attributes of the PRE into
151+
// the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec
152+
// see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and
153+
// https://github.com/getsentry/sentry-javascript/issues/2380
154+
else if ('detail' in e && 'reason' in e.detail) {
155+
error = e.detail.reason;
156+
}
143157
} catch (_oO) {
144158
// no-empty
145159
}

packages/browser/src/loader.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@
200200

201201
// Do the same store/queue/call operations for `onunhandledrejection` event
202202
var _oldOnunhandledrejection = _window[_onunhandledrejection];
203-
_window[_onunhandledrejection] = function(exception) {
203+
_window[_onunhandledrejection] = function(e) {
204204
queue({
205-
p: exception.reason
205+
p: 'reason' in e ? e.reason : 'detail' in e && 'reason' in e.detail ? e.detail.reason : e
206206
});
207207
if (_oldOnunhandledrejection) _oldOnunhandledrejection.apply(_window, arguments);
208208
};

packages/integrations/src/dedupe.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export class Dedupe implements Integration {
6161
const currentMessage = currentEvent.message;
6262
const previousMessage = previousEvent.message;
6363

64-
// If no event has a message, they were both exceptions, so bail out
64+
// If neither event has a message property, they were both exceptions, so bail out
6565
if (!currentMessage && !previousMessage) {
6666
return false;
6767
}
@@ -108,7 +108,7 @@ export class Dedupe implements Integration {
108108
let currentFrames = this._getFramesFromEvent(currentEvent);
109109
let previousFrames = this._getFramesFromEvent(previousEvent);
110110

111-
// If no event has a fingerprint, they are assumed to be the same
111+
// If neither event has a stacktrace, they are assumed to be the same
112112
if (!currentFrames && !previousFrames) {
113113
return true;
114114
}
@@ -178,7 +178,7 @@ export class Dedupe implements Integration {
178178
let currentFingerprint = currentEvent.fingerprint;
179179
let previousFingerprint = previousEvent.fingerprint;
180180

181-
// If no event has a fingerprint, they are assumed to be the same
181+
// If neither event has a fingerprint, they are assumed to be the same
182182
if (!currentFingerprint && !previousFingerprint) {
183183
return true;
184184
}

0 commit comments

Comments
 (0)