From bdc29675fd531e1a1324c3c6eaac6873974230c4 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 10 Dec 2021 17:51:24 -0500 Subject: [PATCH 1/9] ref(browser): Extract global handlers private methods - Move hub and client getters out to a common call and pass them down - Check for integration existence early on - Move private methods into regular functions as they don't use class props --- .../src/integrations/globalhandlers.ts | 193 +++++++++--------- 1 file changed, 98 insertions(+), 95 deletions(-) diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 5911bbeac285..b99f0edcf640 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { getCurrentHub } from '@sentry/core'; -import { Event, Integration, Primitive, Severity } from '@sentry/types'; +import { Event, EventProcessor, Hub, Integration, Primitive, Severity } from '@sentry/types'; import { addExceptionMechanism, addInstrumentationHandler, @@ -52,22 +51,29 @@ export class GlobalHandlers implements Integration { /** * @inheritDoc */ - public setupOnce(): void { + public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { Error.stackTraceLimit = 50; + const hub = getCurrentHub(); + if (!hub.getIntegration(GlobalHandlers)) { + return; + } + const client = hub.getClient(); + const attachStacktrace = client && client.getOptions().attachStacktrace; + if (this._options.onerror) { - logger.log('Global Handler attached: onerror'); - this._installGlobalOnErrorHandler(); + globalHandlerLog('onerror'); + this._installGlobalOnErrorHandler(hub, attachStacktrace); } if (this._options.onunhandledrejection) { - logger.log('Global Handler attached: onunhandledrejection'); - this._installGlobalOnUnhandledRejectionHandler(); + globalHandlerLog('onunhandledrejection'); + this._installGlobalOnUnhandledRejectionHandler(hub, attachStacktrace); } } /** JSDoc */ - private _installGlobalOnErrorHandler(): void { + private _installGlobalOnErrorHandler(hub: Hub, attachStacktrace: boolean | undefined): void { if (this._onErrorHandlerInstalled) { return; } @@ -76,21 +82,18 @@ export class GlobalHandlers implements Integration { // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (data: { msg: any; url: any; line: any; column: any; error: any }) => { const error = data.error; - const currentHub = getCurrentHub(); - const hasIntegration = currentHub.getIntegration(GlobalHandlers); const isFailedOwnDelivery = error && error.__sentry_own_request__ === true; - if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) { + if (shouldIgnoreOnError() || isFailedOwnDelivery) { return; } - const client = currentHub.getClient(); const event = error === undefined && isString(data.msg) - ? this._eventFromIncompleteOnError(data.msg, data.url, data.line, data.column) - : this._enhanceEventWithInitialFrame( + ? _eventFromIncompleteOnError(data.msg, data.url, data.line, data.column) + : _enhanceEventWithInitialFrame( eventFromUnknownInput(error || data.msg, undefined, { - attachStacktrace: client && client.getOptions().attachStacktrace, + attachStacktrace, rejection: false, }), data.url, @@ -103,7 +106,7 @@ export class GlobalHandlers implements Integration { type: 'onerror', }); - currentHub.captureEvent(event, { + hub.captureEvent(event, { originalException: error, }); }, @@ -114,7 +117,7 @@ export class GlobalHandlers implements Integration { } /** JSDoc */ - private _installGlobalOnUnhandledRejectionHandler(): void { + private _installGlobalOnUnhandledRejectionHandler(hub: Hub, attachStacktrace: boolean | undefined): void { if (this._onUnhandledRejectionHandlerInstalled) { return; } @@ -143,19 +146,15 @@ export class GlobalHandlers implements Integration { // no-empty } - const currentHub = getCurrentHub(); - const hasIntegration = currentHub.getIntegration(GlobalHandlers); const isFailedOwnDelivery = error && error.__sentry_own_request__ === true; - - if (!hasIntegration || shouldIgnoreOnError() || isFailedOwnDelivery) { + if (shouldIgnoreOnError() || isFailedOwnDelivery) { return true; } - const client = currentHub.getClient(); const event = isPrimitive(error) - ? this._eventFromRejectionWithPrimitive(error) + ? _eventFromRejectionWithPrimitive(error) : eventFromUnknownInput(error, undefined, { - attachStacktrace: client && client.getOptions().attachStacktrace, + attachStacktrace, rejection: true, }); @@ -166,7 +165,7 @@ export class GlobalHandlers implements Integration { type: 'onunhandledrejection', }); - currentHub.captureEvent(event, { + hub.captureEvent(event, { originalException: error, }); @@ -177,81 +176,85 @@ export class GlobalHandlers implements Integration { this._onUnhandledRejectionHandlerInstalled = true; } +} - /** - * This function creates a stack from an old, error-less onerror handler. - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _eventFromIncompleteOnError(msg: any, url: any, line: any, column: any): Event { - const ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i; - - // If 'message' is ErrorEvent, get real message from inside - let message = isErrorEvent(msg) ? msg.message : msg; - let name; - - const groups = message.match(ERROR_TYPES_RE); - if (groups) { - name = groups[1]; - message = groups[2]; - } - - const event = { - exception: { - values: [ - { - type: name || 'Error', - value: message, - }, - ], - }, - }; +/** + * Create an event from a promise rejection where the `reason` is a primitive. + * + * @param reason: The `reason` property of the promise rejection + * @returns An Event object with an appropriate `exception` value + */ +function _eventFromRejectionWithPrimitive(reason: Primitive): Event { + return { + exception: { + values: [ + { + type: 'UnhandledRejection', + // String() is needed because the Primitive type includes symbols (which can't be automatically stringified) + value: `Non-Error promise rejection captured with value: ${String(reason)}`, + }, + ], + }, + }; +} - return this._enhanceEventWithInitialFrame(event, url, line, column); +/** + * This function creates a stack from an old, error-less onerror handler. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function _eventFromIncompleteOnError(msg: any, url: any, line: any, column: any): Event { + const ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i; + + // If 'message' is ErrorEvent, get real message from inside + let message = isErrorEvent(msg) ? msg.message : msg; + let name; + + const groups = message.match(ERROR_TYPES_RE); + if (groups) { + name = groups[1]; + message = groups[2]; } - /** - * Create an event from a promise rejection where the `reason` is a primitive. - * - * @param reason: The `reason` property of the promise rejection - * @returns An Event object with an appropriate `exception` value - */ - private _eventFromRejectionWithPrimitive(reason: Primitive): Event { - return { - exception: { - values: [ - { - type: 'UnhandledRejection', - // String() is needed because the Primitive type includes symbols (which can't be automatically stringified) - value: `Non-Error promise rejection captured with value: ${String(reason)}`, - }, - ], - }, - }; + const event = { + exception: { + values: [ + { + type: name || 'Error', + value: message, + }, + ], + }, + }; + + return _enhanceEventWithInitialFrame(event, url, line, column); +} + +/** JSDoc */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function _enhanceEventWithInitialFrame(event: Event, url: any, line: any, column: any): Event { + event.exception = event.exception || {}; + event.exception.values = event.exception.values || []; + event.exception.values[0] = event.exception.values[0] || {}; + event.exception.values[0].stacktrace = event.exception.values[0].stacktrace || {}; + event.exception.values[0].stacktrace.frames = event.exception.values[0].stacktrace.frames || []; + + const colno = isNaN(parseInt(column, 10)) ? undefined : column; + const lineno = isNaN(parseInt(line, 10)) ? undefined : line; + const filename = isString(url) && url.length > 0 ? url : getLocationHref(); + + if (event.exception.values[0].stacktrace.frames.length === 0) { + event.exception.values[0].stacktrace.frames.push({ + colno, + filename, + function: '?', + in_app: true, + lineno, + }); } - /** JSDoc */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _enhanceEventWithInitialFrame(event: Event, url: any, line: any, column: any): Event { - event.exception = event.exception || {}; - event.exception.values = event.exception.values || []; - event.exception.values[0] = event.exception.values[0] || {}; - event.exception.values[0].stacktrace = event.exception.values[0].stacktrace || {}; - event.exception.values[0].stacktrace.frames = event.exception.values[0].stacktrace.frames || []; - - const colno = isNaN(parseInt(column, 10)) ? undefined : column; - const lineno = isNaN(parseInt(line, 10)) ? undefined : line; - const filename = isString(url) && url.length > 0 ? url : getLocationHref(); - - if (event.exception.values[0].stacktrace.frames.length === 0) { - event.exception.values[0].stacktrace.frames.push({ - colno, - filename, - function: '?', - in_app: true, - lineno, - }); - } + return event; +} - return event; - } +function globalHandlerLog(type: string): void { + logger.log(`Global Handler attached: ${type}`); } From 0592f71c6407b46d9e1c46473987eb9b9b97b989 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 10 Dec 2021 17:58:08 -0500 Subject: [PATCH 2/9] extract out instrumentation handlers into their own methods: --- .../src/integrations/globalhandlers.ts | 188 +++++++++--------- 1 file changed, 89 insertions(+), 99 deletions(-) diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index b99f0edcf640..82398d12511e 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -61,121 +61,111 @@ export class GlobalHandlers implements Integration { const client = hub.getClient(); const attachStacktrace = client && client.getOptions().attachStacktrace; - if (this._options.onerror) { + if (this._options.onerror && !this._onErrorHandlerInstalled) { globalHandlerLog('onerror'); - this._installGlobalOnErrorHandler(hub, attachStacktrace); + _installGlobalOnErrorHandler(hub, attachStacktrace); + this._onErrorHandlerInstalled = true; } - if (this._options.onunhandledrejection) { + if (this._options.onunhandledrejection && !this._onUnhandledRejectionHandlerInstalled) { globalHandlerLog('onunhandledrejection'); - this._installGlobalOnUnhandledRejectionHandler(hub, attachStacktrace); + _installGlobalOnUnhandledRejectionHandler(hub, attachStacktrace); + this._onUnhandledRejectionHandlerInstalled = true; } } +} - /** JSDoc */ - private _installGlobalOnErrorHandler(hub: Hub, attachStacktrace: boolean | undefined): void { - if (this._onErrorHandlerInstalled) { - return; - } - - addInstrumentationHandler({ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - callback: (data: { msg: any; url: any; line: any; column: any; error: any }) => { - const error = data.error; - const isFailedOwnDelivery = error && error.__sentry_own_request__ === true; - - if (shouldIgnoreOnError() || isFailedOwnDelivery) { - return; - } - - const event = - error === undefined && isString(data.msg) - ? _eventFromIncompleteOnError(data.msg, data.url, data.line, data.column) - : _enhanceEventWithInitialFrame( - eventFromUnknownInput(error || data.msg, undefined, { - attachStacktrace, - rejection: false, - }), - data.url, - data.line, - data.column, - ); - - addExceptionMechanism(event, { - handled: false, - type: 'onerror', - }); - - hub.captureEvent(event, { - originalException: error, - }); - }, - type: 'error', - }); - - this._onErrorHandlerInstalled = true; - } - - /** JSDoc */ - private _installGlobalOnUnhandledRejectionHandler(hub: Hub, attachStacktrace: boolean | undefined): void { - if (this._onUnhandledRejectionHandlerInstalled) { - return; - } +/** JSDoc */ +function _installGlobalOnErrorHandler(hub: Hub, attachStacktrace: boolean | undefined): void { + addInstrumentationHandler({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + callback: (data: { msg: any; url: any; line: any; column: any; error: any }) => { + const error = data.error; + const isFailedOwnDelivery = error && error.__sentry_own_request__ === true; + + if (shouldIgnoreOnError() || isFailedOwnDelivery) { + return; + } + + const event = + error === undefined && isString(data.msg) + ? _eventFromIncompleteOnError(data.msg, data.url, data.line, data.column) + : _enhanceEventWithInitialFrame( + eventFromUnknownInput(error || data.msg, undefined, { + attachStacktrace, + rejection: false, + }), + data.url, + data.line, + data.column, + ); + + addExceptionMechanism(event, { + handled: false, + type: 'onerror', + }); + + hub.captureEvent(event, { + originalException: error, + }); + }, + type: 'error', + }); +} - addInstrumentationHandler({ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - callback: (e: any) => { - let error = e; - - // dig the object of the rejection out of known event types - try { - // PromiseRejectionEvents store the object of the rejection under 'reason' - // see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent - if ('reason' in e) { - error = e.reason; - } - // something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents - // to CustomEvents, moving the `promise` and `reason` attributes of the PRE into - // the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec - // see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and - // https://github.com/getsentry/sentry-javascript/issues/2380 - else if ('detail' in e && 'reason' in e.detail) { - error = e.detail.reason; - } - } catch (_oO) { - // no-empty +/** JSDoc */ +function _installGlobalOnUnhandledRejectionHandler(hub: Hub, attachStacktrace: boolean | undefined): void { + addInstrumentationHandler({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + callback: (e: any) => { + let error = e; + + // dig the object of the rejection out of known event types + try { + // PromiseRejectionEvents store the object of the rejection under 'reason' + // see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent + if ('reason' in e) { + error = e.reason; } - - const isFailedOwnDelivery = error && error.__sentry_own_request__ === true; - if (shouldIgnoreOnError() || isFailedOwnDelivery) { - return true; + // something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents + // to CustomEvents, moving the `promise` and `reason` attributes of the PRE into + // the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec + // see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and + // https://github.com/getsentry/sentry-javascript/issues/2380 + else if ('detail' in e && 'reason' in e.detail) { + error = e.detail.reason; } + } catch (_oO) { + // no-empty + } - const event = isPrimitive(error) - ? _eventFromRejectionWithPrimitive(error) - : eventFromUnknownInput(error, undefined, { - attachStacktrace, - rejection: true, - }); + const isFailedOwnDelivery = error && error.__sentry_own_request__ === true; + if (shouldIgnoreOnError() || isFailedOwnDelivery) { + return true; + } - event.level = Severity.Error; + const event = isPrimitive(error) + ? _eventFromRejectionWithPrimitive(error) + : eventFromUnknownInput(error, undefined, { + attachStacktrace, + rejection: true, + }); - addExceptionMechanism(event, { - handled: false, - type: 'onunhandledrejection', - }); + event.level = Severity.Error; - hub.captureEvent(event, { - originalException: error, - }); + addExceptionMechanism(event, { + handled: false, + type: 'onunhandledrejection', + }); - return; - }, - type: 'unhandledrejection', - }); + hub.captureEvent(event, { + originalException: error, + }); - this._onUnhandledRejectionHandlerInstalled = true; - } + return; + }, + type: 'unhandledrejection', + }); } /** From de2ee7b32fbc701808725c869c05308aeb680098 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 10 Dec 2021 18:11:22 -0500 Subject: [PATCH 3/9] refactor logic into one function --- .../src/integrations/globalhandlers.ts | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 82398d12511e..74ae9ee0cfaf 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { Event, EventProcessor, Hub, Integration, Primitive, Severity } from '@sentry/types'; +import { Event, EventProcessor, Hub, Integration, Primitive, Severity, EventHint } from '@sentry/types'; import { addExceptionMechanism, addInstrumentationHandler, @@ -100,14 +100,7 @@ function _installGlobalOnErrorHandler(hub: Hub, attachStacktrace: boolean | unde data.column, ); - addExceptionMechanism(event, { - handled: false, - type: 'onerror', - }); - - hub.captureEvent(event, { - originalException: error, - }); + addMechanismAndCapture(hub, error, event, 'onerror'); }, type: 'error', }); @@ -153,15 +146,7 @@ function _installGlobalOnUnhandledRejectionHandler(hub: Hub, attachStacktrace: b event.level = Severity.Error; - addExceptionMechanism(event, { - handled: false, - type: 'onunhandledrejection', - }); - - hub.captureEvent(event, { - originalException: error, - }); - + addMechanismAndCapture(hub, error, event, 'onunhandledrejection'); return; }, type: 'unhandledrejection', @@ -248,3 +233,13 @@ function _enhanceEventWithInitialFrame(event: Event, url: any, line: any, column function globalHandlerLog(type: string): void { logger.log(`Global Handler attached: ${type}`); } + +function addMechanismAndCapture(hub: Hub, error: EventHint['originalException'], event: Event, type: string): void { + addExceptionMechanism(event, { + handled: false, + type, + }); + hub.captureEvent(event, { + originalException: error, + }); +} From 00cc3c86bca615e9bbde80dc1fdf31c3b9046d92 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 10 Dec 2021 19:01:11 -0500 Subject: [PATCH 4/9] change conditional --- packages/browser/src/integrations/globalhandlers.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 74ae9ee0cfaf..8d93c8785260 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { Event, EventProcessor, Hub, Integration, Primitive, Severity, EventHint } from '@sentry/types'; +import { Event, EventHint, EventProcessor, Hub, Integration, Primitive, Severity } from '@sentry/types'; import { addExceptionMechanism, addInstrumentationHandler, @@ -61,13 +61,13 @@ export class GlobalHandlers implements Integration { const client = hub.getClient(); const attachStacktrace = client && client.getOptions().attachStacktrace; - if (this._options.onerror && !this._onErrorHandlerInstalled) { + if (this._options.onerror || !this._onErrorHandlerInstalled) { globalHandlerLog('onerror'); _installGlobalOnErrorHandler(hub, attachStacktrace); this._onErrorHandlerInstalled = true; } - if (this._options.onunhandledrejection && !this._onUnhandledRejectionHandlerInstalled) { + if (this._options.onunhandledrejection || !this._onUnhandledRejectionHandlerInstalled) { globalHandlerLog('onunhandledrejection'); _installGlobalOnUnhandledRejectionHandler(hub, attachStacktrace); this._onUnhandledRejectionHandlerInstalled = true; From 52c4af0681c3ff9969944caa4311d0c175882305 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 10 Dec 2021 19:10:57 -0500 Subject: [PATCH 5/9] fix tests this makes me mad that this is a thing --- packages/browser/src/integrations/globalhandlers.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 8d93c8785260..105baf4dd663 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -55,9 +55,6 @@ export class GlobalHandlers implements Integration { Error.stackTraceLimit = 50; const hub = getCurrentHub(); - if (!hub.getIntegration(GlobalHandlers)) { - return; - } const client = hub.getClient(); const attachStacktrace = client && client.getOptions().attachStacktrace; @@ -80,6 +77,9 @@ function _installGlobalOnErrorHandler(hub: Hub, attachStacktrace: boolean | unde addInstrumentationHandler({ // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (data: { msg: any; url: any; line: any; column: any; error: any }) => { + if (!hub.getIntegration(GlobalHandlers)) { + return; + } const error = data.error; const isFailedOwnDelivery = error && error.__sentry_own_request__ === true; @@ -111,6 +111,9 @@ function _installGlobalOnUnhandledRejectionHandler(hub: Hub, attachStacktrace: b addInstrumentationHandler({ // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (e: any) => { + if (!hub.getIntegration(GlobalHandlers)) { + return; + } let error = e; // dig the object of the rejection out of known event types From 332ff207187f217f229af3d57fbaf1fe5f0675ab Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 10 Dec 2021 19:52:50 -0500 Subject: [PATCH 6/9] destructure --- .../browser/src/integrations/globalhandlers.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 105baf4dd663..7775f3059b31 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -80,7 +80,7 @@ function _installGlobalOnErrorHandler(hub: Hub, attachStacktrace: boolean | unde if (!hub.getIntegration(GlobalHandlers)) { return; } - const error = data.error; + const { msg, url, line, column, error } = data; const isFailedOwnDelivery = error && error.__sentry_own_request__ === true; if (shouldIgnoreOnError() || isFailedOwnDelivery) { @@ -88,16 +88,16 @@ function _installGlobalOnErrorHandler(hub: Hub, attachStacktrace: boolean | unde } const event = - error === undefined && isString(data.msg) - ? _eventFromIncompleteOnError(data.msg, data.url, data.line, data.column) + error === undefined && isString(msg) + ? _eventFromIncompleteOnError(msg, url, line, column) : _enhanceEventWithInitialFrame( - eventFromUnknownInput(error || data.msg, undefined, { + eventFromUnknownInput(error || msg, undefined, { attachStacktrace, rejection: false, }), - data.url, - data.line, - data.column, + url, + line, + column, ); addMechanismAndCapture(hub, error, event, 'onerror'); From 41deb4a3c66c06b7231d4e5bc4bb93e94dbcd17c Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 10 Dec 2021 19:59:18 -0500 Subject: [PATCH 7/9] reduce inclusion of unminified names --- .../src/integrations/globalhandlers.ts | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 7775f3059b31..d0f470fab05a 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -185,7 +185,7 @@ function _eventFromIncompleteOnError(msg: any, url: any, line: any, column: any) // If 'message' is ErrorEvent, get real message from inside let message = isErrorEvent(msg) ? msg.message : msg; - let name; + let name = 'Error'; const groups = message.match(ERROR_TYPES_RE); if (groups) { @@ -197,7 +197,7 @@ function _eventFromIncompleteOnError(msg: any, url: any, line: any, column: any) exception: { values: [ { - type: name || 'Error', + type: name, value: message, }, ], @@ -210,18 +210,24 @@ function _eventFromIncompleteOnError(msg: any, url: any, line: any, column: any) /** JSDoc */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function _enhanceEventWithInitialFrame(event: Event, url: any, line: any, column: any): Event { - event.exception = event.exception || {}; - event.exception.values = event.exception.values || []; - event.exception.values[0] = event.exception.values[0] || {}; - event.exception.values[0].stacktrace = event.exception.values[0].stacktrace || {}; - event.exception.values[0].stacktrace.frames = event.exception.values[0].stacktrace.frames || []; + // event.exception + const e = (event.exception = event.exception || {}); + // event.exception.values + const ev = (e.values = e.values || []); + // event.exception.values[0] + const ev0 = (ev[0] = ev[0] || {}); + // event.exception.values[0].stacktrace + const ev0s = (ev0.stacktrace = ev0.stacktrace || {}); + // event.exception.values[0].stacktrace.frames + const ev0sf = (ev0s.frames = ev0s.frames || []); const colno = isNaN(parseInt(column, 10)) ? undefined : column; const lineno = isNaN(parseInt(line, 10)) ? undefined : line; const filename = isString(url) && url.length > 0 ? url : getLocationHref(); - if (event.exception.values[0].stacktrace.frames.length === 0) { - event.exception.values[0].stacktrace.frames.push({ + // event.exception.values[0].stacktrace.frames + if (ev0sf.length === 0) { + ev0sf.push({ colno, filename, function: '?', From 793b104ea95956ad253d18f53b225b64008d7647 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 13 Dec 2021 12:50:24 -0500 Subject: [PATCH 8/9] dynamic dispatch :) --- .../src/integrations/globalhandlers.ts | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index d0f470fab05a..be26d617a5f4 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -13,11 +13,12 @@ import { import { eventFromUnknownInput } from '../eventbuilder'; import { shouldIgnoreOnError } from '../helpers'; +type GlobalHandlersIntegrationsOptionKeys = 'onerror' | 'onunhandledrejection'; + /** JSDoc */ -interface GlobalHandlersIntegrations { - onerror: boolean; - onunhandledrejection: boolean; -} +type GlobalHandlersIntegrations = Record; + +type InstallFunc = (hub: Hub, attachStacktrace: boolean | undefined) => void; /** Global handlers */ export class GlobalHandlers implements Integration { @@ -34,11 +35,14 @@ export class GlobalHandlers implements Integration { /** JSDoc */ private readonly _options: GlobalHandlersIntegrations; - /** JSDoc */ - private _onErrorHandlerInstalled: boolean = false; - - /** JSDoc */ - private _onUnhandledRejectionHandlerInstalled: boolean = false; + /** + * Stores references functions to installing handlers. Will set to undefined + * after they have been run so that they are not used twice. + */ + private _installFunc: Record = { + onerror: _installGlobalOnErrorHandler, + onunhandledrejection: _installGlobalOnUnhandledRejectionHandler, + }; /** JSDoc */ public constructor(options?: GlobalHandlersIntegrations) { @@ -57,17 +61,18 @@ export class GlobalHandlers implements Integration { const hub = getCurrentHub(); const client = hub.getClient(); const attachStacktrace = client && client.getOptions().attachStacktrace; - - if (this._options.onerror || !this._onErrorHandlerInstalled) { - globalHandlerLog('onerror'); - _installGlobalOnErrorHandler(hub, attachStacktrace); - this._onErrorHandlerInstalled = true; - } - - if (this._options.onunhandledrejection || !this._onUnhandledRejectionHandlerInstalled) { - globalHandlerLog('onunhandledrejection'); - _installGlobalOnUnhandledRejectionHandler(hub, attachStacktrace); - this._onUnhandledRejectionHandlerInstalled = true; + const options = this._options; + + // We can disable guard-for-in as we construct the options object above + do checks against + // `this._installFunc` for the property. + // eslint-disable-next-line guard-for-in + for (const key in options) { + const installFunc = this._installFunc[key as GlobalHandlersIntegrationsOptionKeys]; + if (installFunc && options[key as GlobalHandlersIntegrationsOptionKeys]) { + globalHandlerLog(key); + installFunc(hub, attachStacktrace); + this._installFunc[key as GlobalHandlersIntegrationsOptionKeys] = undefined; + } } } } @@ -81,9 +86,7 @@ function _installGlobalOnErrorHandler(hub: Hub, attachStacktrace: boolean | unde return; } const { msg, url, line, column, error } = data; - const isFailedOwnDelivery = error && error.__sentry_own_request__ === true; - - if (shouldIgnoreOnError() || isFailedOwnDelivery) { + if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) { return; } @@ -135,8 +138,7 @@ function _installGlobalOnUnhandledRejectionHandler(hub: Hub, attachStacktrace: b // no-empty } - const isFailedOwnDelivery = error && error.__sentry_own_request__ === true; - if (shouldIgnoreOnError() || isFailedOwnDelivery) { + if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) { return true; } From aa7c3daab04303bc85bb4dc489107cb13252f19b Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 13 Dec 2021 20:34:22 -0500 Subject: [PATCH 9/9] dynamically call hub --- .../src/integrations/globalhandlers.ts | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index be26d617a5f4..ad69493676e9 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { Event, EventHint, EventProcessor, Hub, Integration, Primitive, Severity } from '@sentry/types'; +import { getCurrentHub } from '@sentry/core'; +import { Event, EventHint, Hub, Integration, Primitive, Severity } from '@sentry/types'; import { addExceptionMechanism, addInstrumentationHandler, @@ -18,8 +19,6 @@ type GlobalHandlersIntegrationsOptionKeys = 'onerror' | 'onunhandledrejection'; /** JSDoc */ type GlobalHandlersIntegrations = Record; -type InstallFunc = (hub: Hub, attachStacktrace: boolean | undefined) => void; - /** Global handlers */ export class GlobalHandlers implements Integration { /** @@ -39,7 +38,7 @@ export class GlobalHandlers implements Integration { * Stores references functions to installing handlers. Will set to undefined * after they have been run so that they are not used twice. */ - private _installFunc: Record = { + private _installFunc: Record void) | undefined> = { onerror: _installGlobalOnErrorHandler, onunhandledrejection: _installGlobalOnUnhandledRejectionHandler, }; @@ -55,12 +54,8 @@ export class GlobalHandlers implements Integration { /** * @inheritDoc */ - public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { + public setupOnce(): void { Error.stackTraceLimit = 50; - - const hub = getCurrentHub(); - const client = hub.getClient(); - const attachStacktrace = client && client.getOptions().attachStacktrace; const options = this._options; // We can disable guard-for-in as we construct the options object above + do checks against @@ -70,7 +65,7 @@ export class GlobalHandlers implements Integration { const installFunc = this._installFunc[key as GlobalHandlersIntegrationsOptionKeys]; if (installFunc && options[key as GlobalHandlersIntegrationsOptionKeys]) { globalHandlerLog(key); - installFunc(hub, attachStacktrace); + installFunc(); this._installFunc[key as GlobalHandlersIntegrationsOptionKeys] = undefined; } } @@ -78,10 +73,11 @@ export class GlobalHandlers implements Integration { } /** JSDoc */ -function _installGlobalOnErrorHandler(hub: Hub, attachStacktrace: boolean | undefined): void { +function _installGlobalOnErrorHandler(): void { addInstrumentationHandler({ // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (data: { msg: any; url: any; line: any; column: any; error: any }) => { + const [hub, attachStacktrace] = getHubAndAttachStacktrace(); if (!hub.getIntegration(GlobalHandlers)) { return; } @@ -110,10 +106,11 @@ function _installGlobalOnErrorHandler(hub: Hub, attachStacktrace: boolean | unde } /** JSDoc */ -function _installGlobalOnUnhandledRejectionHandler(hub: Hub, attachStacktrace: boolean | undefined): void { +function _installGlobalOnUnhandledRejectionHandler(): void { addInstrumentationHandler({ // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (e: any) => { + const [hub, attachStacktrace] = getHubAndAttachStacktrace(); if (!hub.getIntegration(GlobalHandlers)) { return; } @@ -254,3 +251,10 @@ function addMechanismAndCapture(hub: Hub, error: EventHint['originalException'], originalException: error, }); } + +function getHubAndAttachStacktrace(): [Hub, boolean | undefined] { + const hub = getCurrentHub(); + const client = hub.getClient(); + const attachStacktrace = client && client.getOptions().attachStacktrace; + return [hub, attachStacktrace]; +}