-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Description
It's recommended to set up Sentry in shared environments like shown below, and only use methods on the scope:
const client = new BrowserClient({ /* options */ });
const scope = new Scope();
scope.setClient(client);
client.init();
// No usage of global methods like `Sentry.captureException`, only on scope
scope.captureException(new Error("example"));Problem
Logger
On SDK initialization, the logger is set up and if you didn't set __SENTRY_DEBUG__: false for your build, the SDK will always act on the global singleton (the __SENTRY__ carrier).
sentry-javascript/packages/core/src/utils/debug-logger.ts
Lines 112 to 118 in 337f538
| function _getLoggerSettings(): { enabled: boolean } { | |
| if (!DEBUG_BUILD) { | |
| return { enabled: false }; | |
| } | |
| return getGlobalSingleton('loggerSettings', () => ({ enabled: false })); | |
| } |
Scopes
Calling scope.captureException() will also initialize the scopes on the global __SENTRY__ carrier, which is a bigger problem as it can potentially leak scope data if there are multiple Sentry instances.
scope.captureException() calls the global getIsolationScope(). This was introduced in the following PR, in order to use the session from the isolation scope: #14860
What happens, is that scope.captureException() calls captureException with 3 paramters:
sentry-javascript/packages/core/src/scope.ts
Lines 708 to 717 in 337f538
| this._client.captureException( | |
| exception, | |
| { | |
| originalException: exception, | |
| syntheticException, | |
| ...hint, | |
| event_id: eventId, | |
| }, | |
| this, | |
| ); |
Eventually, this is forwarded until _captureEvent, where by default, the 4th parameter calls getIsolationScope():
sentry-javascript/packages/core/src/client.ts
Lines 1235 to 1240 in eb4382c
| protected _captureEvent( | |
| event: Event, | |
| hint: EventHint = {}, | |
| currentScope = getCurrentScope(), | |
| isolationScope = getIsolationScope(), | |
| ): PromiseLike<string | undefined> { |
Reproduction
https://github.com/Lms24/repro-js-shared-environments
Ideas
scope.captureExceptioncould receive an optionalscopeas a third parameter which will be used as theisolationScope. But then, the usage would bescope.captureException(new Error(), {}, scope).- Adding a
sharedEnvSetup: booleanto the initialization options which would allow us to conditionally use certain APIs (or for example, store the logger settings in the module scope, instead of a global scope)