From bdae9bb396cec29048475bfcd24d14309ed1019d Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 5 Apr 2022 11:52:32 -0400 Subject: [PATCH 1/2] feat(utils): Introduce getGlobalSingleton helper This helper abstracts away the logic of getting an variable from the global `__SENTRY__` object. It does this by introducing a new `getGlobalSingleton` utility function. For now, this is used by the event processors and hub logic. In an upcoming patch, we'll update the logger logic to also use this utility. --- packages/hub/src/hub.ts | 19 ++++++++++++------- packages/hub/src/scope.ts | 9 ++------- packages/utils/src/global.ts | 13 +++++++++++++ 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/packages/hub/src/hub.ts b/packages/hub/src/hub.ts index 5aee3969afed..e07e248a787c 100644 --- a/packages/hub/src/hub.ts +++ b/packages/hub/src/hub.ts @@ -20,7 +20,15 @@ import { TransactionContext, User, } from '@sentry/types'; -import { consoleSandbox, dateTimestampInSeconds, getGlobalObject, isNodeEnv, logger, uuid4 } from '@sentry/utils'; +import { + consoleSandbox, + dateTimestampInSeconds, + getGlobalObject, + getGlobalSingleton, + isNodeEnv, + logger, + uuid4, +} from '@sentry/utils'; import { IS_DEBUG_BUILD } from './flags'; import { Scope } from './scope'; @@ -617,10 +625,7 @@ function hasHubOnCarrier(carrier: Carrier): boolean { * @hidden */ export function getHubFromCarrier(carrier: Carrier): Hub { - if (carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub) return carrier.__SENTRY__.hub; - carrier.__SENTRY__ = carrier.__SENTRY__ || {}; - carrier.__SENTRY__.hub = new Hub(); - return carrier.__SENTRY__.hub; + return getGlobalSingleton('hub', () => new Hub(), carrier); } /** @@ -631,7 +636,7 @@ export function getHubFromCarrier(carrier: Carrier): Hub { */ export function setHubOnCarrier(carrier: Carrier, hub: Hub): boolean { if (!carrier) return false; - carrier.__SENTRY__ = carrier.__SENTRY__ || {}; - carrier.__SENTRY__.hub = hub; + const sentry = (carrier.__SENTRY__ = carrier.__SENTRY__ || {}); + sentry.hub = hub; return true; } diff --git a/packages/hub/src/scope.ts b/packages/hub/src/scope.ts index 17ce4eef8458..9243cd409b66 100644 --- a/packages/hub/src/scope.ts +++ b/packages/hub/src/scope.ts @@ -18,7 +18,7 @@ import { Transaction, User, } from '@sentry/types'; -import { dateTimestampInSeconds, getGlobalObject, isPlainObject, isThenable, SyncPromise } from '@sentry/utils'; +import { dateTimestampInSeconds, getGlobalSingleton, isPlainObject, isThenable, SyncPromise } from '@sentry/utils'; import { Session } from './session'; @@ -522,12 +522,7 @@ export class Scope implements ScopeInterface { * Returns the global event processors. */ function getGlobalEventProcessors(): EventProcessor[] { - /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */ - const global = getGlobalObject(); - global.__SENTRY__ = global.__SENTRY__ || {}; - global.__SENTRY__.globalEventProcessors = global.__SENTRY__.globalEventProcessors || []; - return global.__SENTRY__.globalEventProcessors; - /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */ + return getGlobalSingleton('globalEventProcessors', () => []); } /** diff --git a/packages/utils/src/global.ts b/packages/utils/src/global.ts index 7ede3f8fe58e..85c86953c5f2 100644 --- a/packages/utils/src/global.ts +++ b/packages/utils/src/global.ts @@ -44,3 +44,16 @@ export function getGlobalObject(): T & SentryGlobal { : fallbackGlobalObject ) as T & SentryGlobal; } + +/** + * Returns a global singleton contained on the global `__SENTRY__` object. + * + * @param name name of the global singleton on __SENTRY__ + * @param creator creation function + * @returns the singleton + */ +export function getGlobalSingleton(name: keyof SentryGlobal['__SENTRY__'], creator: () => T, obj?: unknown): T { + const global = (obj || getGlobalObject()) as SentryGlobal; + const sentry = (global.__SENTRY__ = global.__SENTRY__ || {}); + return sentry[name] || (sentry[name] = creator()); +} From 393962bd5aa5c41037c34a4f1028ff7d923d3285 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 5 Apr 2022 14:03:29 -0400 Subject: [PATCH 2/2] address PR review --- packages/hub/src/hub.ts | 4 ++-- packages/utils/src/global.ts | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/hub/src/hub.ts b/packages/hub/src/hub.ts index e07e248a787c..67761953abfa 100644 --- a/packages/hub/src/hub.ts +++ b/packages/hub/src/hub.ts @@ -636,7 +636,7 @@ export function getHubFromCarrier(carrier: Carrier): Hub { */ export function setHubOnCarrier(carrier: Carrier, hub: Hub): boolean { if (!carrier) return false; - const sentry = (carrier.__SENTRY__ = carrier.__SENTRY__ || {}); - sentry.hub = hub; + const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {}); + __SENTRY__.hub = hub; return true; } diff --git a/packages/utils/src/global.ts b/packages/utils/src/global.ts index 85c86953c5f2..a8b4b7ce0b0e 100644 --- a/packages/utils/src/global.ts +++ b/packages/utils/src/global.ts @@ -46,14 +46,19 @@ export function getGlobalObject(): T & SentryGlobal { } /** - * Returns a global singleton contained on the global `__SENTRY__` object. + * Returns a global singleton contained in the global `__SENTRY__` object. + * + * If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory + * function and added to the `__SENTRY__` object. * * @param name name of the global singleton on __SENTRY__ - * @param creator creation function + * @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__` + * @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `getGlobalObject`'s return value * @returns the singleton */ export function getGlobalSingleton(name: keyof SentryGlobal['__SENTRY__'], creator: () => T, obj?: unknown): T { const global = (obj || getGlobalObject()) as SentryGlobal; - const sentry = (global.__SENTRY__ = global.__SENTRY__ || {}); - return sentry[name] || (sentry[name] = creator()); + const __SENTRY__ = (global.__SENTRY__ = global.__SENTRY__ || {}); + const singleton = __SENTRY__[name] || (__SENTRY__[name] = creator()); + return singleton; }