Skip to content

Commit e74dac7

Browse files
author
Luca Forstner
authored
feat(core): Add withIsolationScope (#10141)
1 parent 72ddbde commit e74dac7

File tree

15 files changed

+404
-205
lines changed

15 files changed

+404
-205
lines changed

packages/astro/src/index.server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export {
4646
// eslint-disable-next-line deprecation/deprecation
4747
trace,
4848
withScope,
49+
withIsolationScope,
4950
autoDiscoverNodePerformanceMonitoringIntegrations,
5051
makeNodeTransport,
5152
defaultIntegrations,

packages/browser/src/exports.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export {
6060
setTags,
6161
setUser,
6262
withScope,
63+
withIsolationScope,
6364
FunctionToString,
6465
InboundFilters,
6566
metrics,

packages/bun/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export {
6666
// eslint-disable-next-line deprecation/deprecation
6767
trace,
6868
withScope,
69+
withIsolationScope,
6970
captureCheckIn,
7071
withMonitor,
7172
setMeasurement,

packages/core/src/exports.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { GLOBAL_OBJ, isThenable, logger, timestampInSeconds, uuid4 } from '@sent
2525
import { DEFAULT_ENVIRONMENT } from './constants';
2626
import { DEBUG_BUILD } from './debug-build';
2727
import type { Hub } from './hub';
28+
import { runWithAsyncContext } from './hub';
2829
import { getCurrentHub, getIsolationScope } from './hub';
2930
import type { Scope } from './scope';
3031
import { closeSession, makeSession, updateSession } from './session';
@@ -35,7 +36,7 @@ import { parseEventHintOrCaptureContext } from './utils/prepareEvent';
3536
* Captures an exception event and sends it to Sentry.
3637
*
3738
* @param exception The exception to capture.
38-
* @param hint Optinal additional data to attach to the Sentry event.
39+
* @param hint Optional additional data to attach to the Sentry event.
3940
* @returns the id of the captured Sentry event.
4041
*/
4142
export function captureException(
@@ -208,6 +209,26 @@ export function withScope<T>(
208209
return getCurrentHub().withScope(rest[0]);
209210
}
210211

212+
/**
213+
* Attempts to fork the current isolation scope and the current scope based on the current async context strategy. If no
214+
* async context strategy is set, the isolation scope and the current scope will not be forked (this is currently the
215+
* case, for example, in the browser).
216+
*
217+
* Usage of this function in environments without async context strategy is discouraged and may lead to unexpected behaviour.
218+
*
219+
* This function is intended for Sentry SDK and SDK integration development. It is not recommended to be used in "normal"
220+
* applications directly because it comes with pitfalls. Use at your own risk!
221+
*
222+
* @param callback The callback in which the passed isolation scope is active. (Note: In environments without async
223+
* context strategy, the currently active isolation scope may change within execution of the callback.)
224+
* @returns The same value that `callback` returns.
225+
*/
226+
export function withIsolationScope<T>(callback: (isolationScope: Scope) => T): T {
227+
return runWithAsyncContext(() => {
228+
return callback(getIsolationScope());
229+
});
230+
}
231+
211232
/**
212233
* Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation.
213234
*

packages/core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export {
2929
setTags,
3030
setUser,
3131
withScope,
32+
withIsolationScope,
3233
getClient,
3334
getCurrentScope,
3435
startSession,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { getCurrentHub, runWithAsyncContext } from '../../src';
2+
3+
describe('runWithAsyncContext()', () => {
4+
it('without strategy hubs should be equal', () => {
5+
runWithAsyncContext(() => {
6+
const hub1 = getCurrentHub();
7+
runWithAsyncContext(() => {
8+
const hub2 = getCurrentHub();
9+
expect(hub1).toBe(hub2);
10+
});
11+
});
12+
});
13+
});

packages/core/test/lib/scope.test.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Attachment, Breadcrumb, Client, Event } from '@sentry/types';
2-
import { applyScopeDataToEvent } from '../../src';
2+
import { applyScopeDataToEvent, getCurrentScope, getIsolationScope, withIsolationScope } from '../../src';
33
import { Scope, getGlobalScope, setGlobalScope } from '../../src/scope';
44

55
describe('Scope', () => {
@@ -465,3 +465,41 @@ describe('Scope', () => {
465465
});
466466
});
467467
});
468+
469+
describe('isolation scope', () => {
470+
describe('withIsolationScope()', () => {
471+
it('will pass an isolation scope without Sentry.init()', done => {
472+
expect.assertions(1);
473+
withIsolationScope(scope => {
474+
expect(scope).toBeDefined();
475+
done();
476+
});
477+
});
478+
479+
it('will make the passed isolation scope the active isolation scope within the callback', done => {
480+
expect.assertions(1);
481+
withIsolationScope(scope => {
482+
expect(getIsolationScope()).toBe(scope);
483+
done();
484+
});
485+
});
486+
487+
it('will pass an isolation scope that is different from the current active scope', done => {
488+
expect.assertions(1);
489+
withIsolationScope(scope => {
490+
expect(getCurrentScope()).not.toBe(scope);
491+
done();
492+
});
493+
});
494+
495+
it('will always make the inner most passed scope the current scope when nesting calls', done => {
496+
expect.assertions(1);
497+
withIsolationScope(_scope1 => {
498+
withIsolationScope(scope2 => {
499+
expect(getIsolationScope()).toBe(scope2);
500+
done();
501+
});
502+
});
503+
});
504+
});
505+
});

packages/deno/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export {
6565
// eslint-disable-next-line deprecation/deprecation
6666
trace,
6767
withScope,
68+
withIsolationScope,
6869
captureCheckIn,
6970
withMonitor,
7071
setMeasurement,

packages/node/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export {
6565
// eslint-disable-next-line deprecation/deprecation
6666
trace,
6767
withScope,
68+
withIsolationScope,
6869
captureCheckIn,
6970
withMonitor,
7071
setMeasurement,

0 commit comments

Comments
 (0)