Skip to content

Commit 81ca2e8

Browse files
committed
[v7] Read scope instantly after capture calls and fix withScope function
1 parent d2ec242 commit 81ca2e8

File tree

2 files changed

+43
-24
lines changed

2 files changed

+43
-24
lines changed

packages/core/src/baseclient.ts

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,11 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
127127
public captureException(exception: unknown, captureContext: CaptureContext = {}): string | undefined {
128128
// TODO: This is broken. a) we dont pass event_id in hint anymore, b) its sync value assigned in async callback
129129
let eventId = captureContext.hint?.event_id;
130+
const scope = this._getEventScope(captureContext);
130131

131132
this._process(
132133
this._eventFromException(exception, captureContext)
133-
.then(event => this._captureEvent(event, captureContext))
134+
.then(event => this._captureEvent(event, captureContext, scope))
134135
.then(result => {
135136
eventId = result;
136137
}),
@@ -144,14 +145,15 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
144145
*/
145146
public captureMessage(message: string, captureContext: CaptureContext = {}): string | undefined {
146147
let eventId = captureContext.hint?.event_id;
148+
const scope = this._getEventScope(captureContext);
147149

148150
const promisedEvent = isPrimitive(message)
149151
? this._eventFromMessage(String(message), captureContext)
150152
: this._eventFromException(message, captureContext);
151153

152154
this._process(
153155
promisedEvent
154-
.then(event => this._captureEvent(event, captureContext))
156+
.then(event => this._captureEvent(event, captureContext, scope))
155157
.then(result => {
156158
eventId = result;
157159
}),
@@ -165,9 +167,10 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
165167
*/
166168
public captureEvent(event: SentryEvent, captureContext: CaptureContext = {}): string | undefined {
167169
let eventId = captureContext.hint?.event_id;
170+
const scope = this._getEventScope(captureContext);
168171

169172
this._process(
170-
this._captureEvent(event, captureContext).then(result => {
173+
this._captureEvent(event, captureContext, scope).then(result => {
171174
eventId = result;
172175
}),
173176
);
@@ -298,6 +301,16 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
298301
});
299302
}
300303

304+
// We need this function to be eagerly called in `capture` calls, because whole processing pipeline is async,
305+
// where withScope works in sync way
306+
protected _getEventScope(captureContext: CaptureContext): ScopeLike {
307+
return captureContext.scope instanceof Scope
308+
? captureContext.scope
309+
: this.getScope()
310+
.clone()
311+
.update(captureContext.scope);
312+
}
313+
301314
/**
302315
* Adds common information to events.
303316
*
@@ -312,7 +325,11 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
312325
* @param scope A scope containing event metadata.
313326
* @returns A new event with more information.
314327
*/
315-
protected _prepareEvent(event: SentryEvent, captureContext: CaptureContext): PromiseLike<SentryEvent | null> {
328+
protected _prepareEvent(
329+
event: SentryEvent,
330+
captureContext: CaptureContext,
331+
scope: ScopeLike,
332+
): PromiseLike<SentryEvent | null> {
316333
const { normalizeDepth = 3 } = this.options;
317334
const prepared: SentryEvent = {
318335
...event,
@@ -323,14 +340,6 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
323340
this._applyClientOptions(prepared);
324341
this._applyIntegrationsMetadata(prepared);
325342

326-
// TODO: We should be able to remove scope as dependency here somehow
327-
const scope =
328-
captureContext.scope instanceof Scope
329-
? captureContext.scope
330-
: this.getScope()
331-
.clone()
332-
.update(captureContext.scope);
333-
334343
return scope.applyToEvent(prepared, captureContext.hint).then(event => {
335344
if (typeof normalizeDepth === 'number' && normalizeDepth > 0) {
336345
return this._normalizeEvent(event, normalizeDepth);
@@ -451,8 +460,12 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
451460
* @param hint
452461
* @param scope
453462
*/
454-
protected _captureEvent(event: SentryEvent, captureContext: CaptureContext): PromiseLike<string | undefined> {
455-
return this._processEvent(event, captureContext).then(
463+
protected _captureEvent(
464+
event: SentryEvent,
465+
captureContext: CaptureContext,
466+
scope: ScopeLike,
467+
): PromiseLike<string | undefined> {
468+
return this._processEvent(event, captureContext, scope).then(
456469
finalEvent => {
457470
// TODO: Make it configurable or move to @sentry/integration-browser-breadcrumbs
458471
const eventType = finalEvent.type === 'transaction' ? 'transaction' : 'event';
@@ -489,7 +502,11 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
489502
* @param scope A scope containing event metadata.
490503
* @returns A Promise that resolves with the event or rejects in case event was/will not be send.
491504
*/
492-
protected _processEvent(event: SentryEvent, captureContext: CaptureContext): PromiseLike<SentryEvent> {
505+
protected _processEvent(
506+
event: SentryEvent,
507+
captureContext: CaptureContext,
508+
scope: ScopeLike,
509+
): PromiseLike<SentryEvent> {
493510
// eslint-disable-next-line @typescript-eslint/unbound-method
494511
const { beforeSend, sampleRate } = this.options;
495512

@@ -509,7 +526,7 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
509526
);
510527
}
511528

512-
return this._prepareEvent(event, captureContext)
529+
return this._prepareEvent(event, captureContext, scope)
513530
.then(prepared => {
514531
if (prepared === null) {
515532
throw new SentryError('An event processor returned null, will not send event.');

packages/minimal/src/index.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,24 @@ export {
1818
} from './scope';
1919

2020
export function configureScope(callback: (scope: ScopeLike) => void): void {
21-
const scope = getCurrentClient()?.getScope();
22-
if (scope) {
23-
callback(scope);
21+
const client = getCurrentClient();
22+
if (client) {
23+
callback(client.getScope());
2424
}
2525
}
2626

2727
export function withScope(callback: (scope: ScopeLike) => void): void {
28-
const scope = getCurrentClient()
29-
?.getScope()
30-
?.clone();
28+
const client = getCurrentClient();
3129

32-
if (scope) {
30+
if (client) {
31+
const currentScope = client.getScope();
32+
const newScope = currentScope.clone();
3333
try {
34-
callback(scope);
34+
client.setScope(newScope);
35+
callback(newScope);
3536
} catch (_oO) {
3637
// no-empty
3738
}
39+
client.setScope(currentScope);
3840
}
3941
}

0 commit comments

Comments
 (0)