Skip to content

Commit 2b4d56b

Browse files
authored
ref(core): Replace Scope.clone() with non-static scope.clone() (#9801)
To avoid this static method there. It is deprecated to use `Scope.clone()` (but still works), but better to just use `scope.clone()` or `new Scope()` directly.
1 parent 1512d23 commit 2b4d56b

File tree

10 files changed

+78
-74
lines changed

10 files changed

+78
-74
lines changed

packages/core/src/hub.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export class Hub implements HubInterface {
142142
*/
143143
public pushScope(): Scope {
144144
// We want to clone the content of prev scope
145-
const scope = Scope.clone(this.getScope());
145+
const scope = this.getScope().clone();
146146
this.getStack().push({
147147
client: this.getClient(),
148148
scope,
@@ -578,7 +578,7 @@ export function ensureHubOnCarrier(carrier: Carrier, parent: Hub = getGlobalHub(
578578
// If there's no hub on current domain, or it's an old API, assign a new one
579579
if (!hasHubOnCarrier(carrier) || getHubFromCarrier(carrier).isOlderThan(API_VERSION)) {
580580
const globalHubTopStack = parent.getStackTop();
581-
setHubOnCarrier(carrier, new Hub(globalHubTopStack.client, Scope.clone(globalHubTopStack.scope)));
581+
setHubOnCarrier(carrier, new Hub(globalHubTopStack.client, globalHubTopStack.scope.clone()));
582582
}
583583
}
584584

packages/core/src/scope.ts

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -110,27 +110,33 @@ export class Scope implements ScopeInterface {
110110

111111
/**
112112
* Inherit values from the parent scope.
113-
* @param scope to clone.
113+
* @deprecated Use `scope.clone()` and `new Scope()` instead.
114114
*/
115115
public static clone(scope?: Scope): Scope {
116+
return scope ? scope.clone() : new Scope();
117+
}
118+
119+
/**
120+
* Clone this scope instance.
121+
*/
122+
public clone(): Scope {
116123
const newScope = new Scope();
117-
if (scope) {
118-
newScope._breadcrumbs = [...scope._breadcrumbs];
119-
newScope._tags = { ...scope._tags };
120-
newScope._extra = { ...scope._extra };
121-
newScope._contexts = { ...scope._contexts };
122-
newScope._user = scope._user;
123-
newScope._level = scope._level;
124-
newScope._span = scope._span;
125-
newScope._session = scope._session;
126-
newScope._transactionName = scope._transactionName;
127-
newScope._fingerprint = scope._fingerprint;
128-
newScope._eventProcessors = [...scope._eventProcessors];
129-
newScope._requestSession = scope._requestSession;
130-
newScope._attachments = [...scope._attachments];
131-
newScope._sdkProcessingMetadata = { ...scope._sdkProcessingMetadata };
132-
newScope._propagationContext = { ...scope._propagationContext };
133-
}
124+
newScope._breadcrumbs = [...this._breadcrumbs];
125+
newScope._tags = { ...this._tags };
126+
newScope._extra = { ...this._extra };
127+
newScope._contexts = { ...this._contexts };
128+
newScope._user = this._user;
129+
newScope._level = this._level;
130+
newScope._span = this._span;
131+
newScope._session = this._session;
132+
newScope._transactionName = this._transactionName;
133+
newScope._fingerprint = this._fingerprint;
134+
newScope._eventProcessors = [...this._eventProcessors];
135+
newScope._requestSession = this._requestSession;
136+
newScope._attachments = [...this._attachments];
137+
newScope._sdkProcessingMetadata = { ...this._sdkProcessingMetadata };
138+
newScope._propagationContext = { ...this._propagationContext };
139+
134140
return newScope;
135141
}
136142

packages/core/src/utils/prepareEvent.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,7 @@ export function prepareEvent(
7474

7575
// If we have scope given to us, use it as the base for further modifications.
7676
// This allows us to prevent unnecessary copying of data if `captureContext` is not provided.
77-
let finalScope = scope;
78-
if (hint.captureContext) {
79-
finalScope = Scope.clone(finalScope).update(hint.captureContext);
80-
}
77+
const finalScope = getFinalScope(scope, hint.captureContext);
8178

8279
if (hint.mechanism) {
8380
addExceptionMechanism(prepared, hint.mechanism);
@@ -349,6 +346,16 @@ function normalizeEvent(event: Event | null, depth: number, maxBreadth: number):
349346
return normalized;
350347
}
351348

349+
function getFinalScope(scope: Scope | undefined, captureContext: CaptureContext | undefined): Scope | undefined {
350+
if (!captureContext) {
351+
return scope;
352+
}
353+
354+
const finalScope = scope ? scope.clone() : new Scope();
355+
finalScope.update(captureContext);
356+
return finalScope;
357+
}
358+
352359
/**
353360
* Parse either an `EventHint` directly, or convert a `CaptureContext` to an `EventHint`.
354361
* This is used to allow to update method signatures that used to accept a `CaptureContext` but should now accept an `EventHint`.

packages/opentelemetry-node/test/spanprocessor.test.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,7 @@ import type { Span as OtelSpan } from '@opentelemetry/sdk-trace-base';
55
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
66
import { SemanticAttributes, SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
77
import type { SpanStatusType } from '@sentry/core';
8-
import {
9-
Hub,
10-
Scope,
11-
Span as SentrySpan,
12-
Transaction,
13-
addTracingExtensions,
14-
createTransport,
15-
makeMain,
16-
} from '@sentry/core';
8+
import { Hub, Span as SentrySpan, Transaction, addTracingExtensions, createTransport, makeMain } from '@sentry/core';
179
import { NodeClient } from '@sentry/node';
1810
import { resolvedSyncPromise } from '@sentry/utils';
1911

@@ -973,7 +965,7 @@ describe('SentrySpanProcessor', () => {
973965
hub = new Hub(client);
974966
makeMain(hub);
975967

976-
const newHub = new Hub(client, Scope.clone(hub.getScope()));
968+
const newHub = new Hub(client, hub.getScope().clone());
977969
newHub.configureScope(scope => {
978970
scope.setTag('foo', 'bar');
979971
});

packages/opentelemetry/src/contextManager.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import type { Context, ContextManager } from '@opentelemetry/api';
22
import type { Carrier, Hub } from '@sentry/core';
3+
import { ensureHubOnCarrier } from '@sentry/core';
34

4-
import { ensureHubOnCarrier, getCurrentHub, getHubFromCarrier } from './custom/hub';
5+
import { getCurrentHub, getHubFromCarrier } from './custom/hub';
56
import { setHubOnContext } from './utils/contextData';
67

78
function createNewHub(parent: Hub | undefined): Hub {

packages/opentelemetry/src/custom/client.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { trace } from '@opentelemetry/api';
33
import type { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';
44
import type { BaseClient, Scope } from '@sentry/core';
55
import { SDK_VERSION } from '@sentry/core';
6-
import type { Client, Event, EventHint } from '@sentry/types';
6+
import type { CaptureContext, Client, Event, EventHint } from '@sentry/types';
77

88
import type { OpenTelemetryClient as OpenTelemetryClientInterface } from '../types';
99
import { OpenTelemetryScope } from './scope';
@@ -65,14 +65,14 @@ export function wrapClientClass<
6565

6666
/**
6767
* Extends the base `_prepareEvent` so that we can properly handle `captureContext`.
68-
* This uses `Scope.clone()`, which we need to replace with `NodeExperimentalScope.clone()` for this client.
68+
* This uses `Scope.clone()`, which we need to replace with `OpenTelemetryScope.clone()` for this client.
6969
*/
7070
protected _prepareEvent(event: Event, hint: EventHint, scope?: Scope): PromiseLike<Event | null> {
7171
let actualScope = scope;
7272

7373
// Remove `captureContext` hint and instead clone already here
7474
if (hint && hint.captureContext) {
75-
actualScope = OpenTelemetryScope.clone(scope);
75+
actualScope = getFinalScope(scope, hint.captureContext);
7676
delete hint.captureContext;
7777
}
7878

@@ -83,3 +83,9 @@ export function wrapClientClass<
8383
return OpenTelemetryClient as unknown as WrappedClassConstructor;
8484
}
8585
/* eslint-enable @typescript-eslint/no-explicit-any */
86+
87+
function getFinalScope(scope: Scope | undefined, captureContext: CaptureContext): Scope | undefined {
88+
const finalScope = scope ? scope.clone() : new OpenTelemetryScope();
89+
finalScope.update(captureContext);
90+
return finalScope;
91+
}

packages/opentelemetry/src/custom/hub.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,6 @@ export class OpenTelemetryHub extends Hub {
1313
public constructor(client?: Client, scope: Scope = new OpenTelemetryScope()) {
1414
super(client, scope);
1515
}
16-
17-
/**
18-
* @inheritDoc
19-
*/
20-
public pushScope(): Scope {
21-
// We want to clone the content of prev scope
22-
const scope = OpenTelemetryScope.clone(this.getScope());
23-
this.getStack().push({
24-
client: this.getClient(),
25-
scope,
26-
});
27-
return scope;
28-
}
2916
}
3017

3118
/** Custom getClient method that uses the custom hub. */
@@ -110,10 +97,7 @@ export function ensureHubOnCarrier(carrier: Carrier, parent: Hub = getGlobalHub(
11097
// If there's no hub on current domain, or it's an old API, assign a new one
11198
if (!hasHubOnCarrier(carrier) || getHubFromCarrier(carrier).isOlderThan(API_VERSION)) {
11299
const globalHubTopStack = parent.getStackTop();
113-
setHubOnCarrier(
114-
carrier,
115-
new OpenTelemetryHub(globalHubTopStack.client, OpenTelemetryScope.clone(globalHubTopStack.scope)),
116-
);
100+
setHubOnCarrier(carrier, new OpenTelemetryHub(globalHubTopStack.client, globalHubTopStack.scope.clone()));
117101
}
118102
}
119103

packages/opentelemetry/src/custom/scope.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,30 @@ export class OpenTelemetryScope extends Scope {
2323
* @inheritDoc
2424
*/
2525
public static clone(scope?: Scope): Scope {
26+
return scope ? scope.clone() : new OpenTelemetryScope();
27+
}
28+
29+
/**
30+
* Clone this scope instance.
31+
*/
32+
public clone(): OpenTelemetryScope {
2633
const newScope = new OpenTelemetryScope();
27-
if (scope) {
28-
newScope._breadcrumbs = [...scope['_breadcrumbs']];
29-
newScope._tags = { ...scope['_tags'] };
30-
newScope._extra = { ...scope['_extra'] };
31-
newScope._contexts = { ...scope['_contexts'] };
32-
newScope._user = scope['_user'];
33-
newScope._level = scope['_level'];
34-
newScope._span = scope['_span'];
35-
newScope._session = scope['_session'];
36-
newScope._transactionName = scope['_transactionName'];
37-
newScope._fingerprint = scope['_fingerprint'];
38-
newScope._eventProcessors = [...scope['_eventProcessors']];
39-
newScope._requestSession = scope['_requestSession'];
40-
newScope._attachments = [...scope['_attachments']];
41-
newScope._sdkProcessingMetadata = { ...scope['_sdkProcessingMetadata'] };
42-
newScope._propagationContext = { ...scope['_propagationContext'] };
43-
}
34+
newScope._breadcrumbs = [...this['_breadcrumbs']];
35+
newScope._tags = { ...this['_tags'] };
36+
newScope._extra = { ...this['_extra'] };
37+
newScope._contexts = { ...this['_contexts'] };
38+
newScope._user = this['_user'];
39+
newScope._level = this['_level'];
40+
newScope._span = this['_span'];
41+
newScope._session = this['_session'];
42+
newScope._transactionName = this['_transactionName'];
43+
newScope._fingerprint = this['_fingerprint'];
44+
newScope._eventProcessors = [...this['_eventProcessors']];
45+
newScope._requestSession = this['_requestSession'];
46+
newScope._attachments = [...this['_attachments']];
47+
newScope._sdkProcessingMetadata = { ...this['_sdkProcessingMetadata'] };
48+
newScope._propagationContext = { ...this['_propagationContext'] };
49+
4450
return newScope;
4551
}
4652

packages/opentelemetry/src/spanExporter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ function maybeSend(spans: ReadableSpan[]): ReadableSpan[] {
112112

113113
// Now finish the transaction, which will send it together with all the spans
114114
// We make sure to use the current span as the activeSpan for this transaction
115-
const scope = getSpanScope(span);
116-
const forkedScope = OpenTelemetryScope.clone(scope as OpenTelemetryScope | undefined) as OpenTelemetryScope;
115+
const scope = getSpanScope(span) as OpenTelemetryScope | undefined;
116+
const forkedScope = scope ? scope.clone() : new OpenTelemetryScope();
117117
forkedScope.activeSpan = span as unknown as Span;
118118

119119
transaction.finishWithScope(convertOtelTimeToSeconds(span.endTime), forkedScope);

packages/opentelemetry/test/custom/scope.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ describe('NodeExperimentalScope', () => {
3030
scope['_attachments'] = [{ data: '123', filename: 'test.txt' }];
3131
scope['_sdkProcessingMetadata'] = { sdk: 'bar' };
3232

33+
// eslint-disable-next-line deprecation/deprecation
3334
const scope2 = OpenTelemetryScope.clone(scope);
3435

3536
expect(scope2).toBeInstanceOf(OpenTelemetryScope);
@@ -68,6 +69,7 @@ describe('NodeExperimentalScope', () => {
6869
});
6970

7071
it('clone() works without existing scope', () => {
72+
// eslint-disable-next-line deprecation/deprecation
7173
const scope = OpenTelemetryScope.clone(undefined);
7274

7375
expect(scope).toBeInstanceOf(OpenTelemetryScope);

0 commit comments

Comments
 (0)