Skip to content

feat(core): Add setClient() and getClient() to Scope #10055

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions packages/core/src/hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,33 @@ export class Hub implements HubInterface {
*/
public constructor(
client?: Client,
scope: Scope = new Scope(),
isolationScope = new Scope(),
scope?: Scope,
isolationScope?: Scope,
private readonly _version: number = API_VERSION,
) {
this._stack = [{ scope }];
let assignedScope;
if (!scope) {
assignedScope = new Scope();
assignedScope.setClient(client);
} else {
assignedScope = scope;
}

let assignedIsolationScope;
if (!isolationScope) {
assignedIsolationScope = new Scope();
assignedIsolationScope.setClient(client);
} else {
assignedIsolationScope = isolationScope;
}

this._stack = [{ scope: assignedScope }];

if (client) {
this.bindClient(client);
}

this._isolationScope = isolationScope;
this._isolationScope = assignedIsolationScope;
}

/**
Expand Down
19 changes: 19 additions & 0 deletions packages/core/src/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {
Attachment,
Breadcrumb,
CaptureContext,
Client,
Context,
Contexts,
Event,
Expand Down Expand Up @@ -100,6 +101,9 @@ export class Scope implements ScopeInterface {
/** Request Mode Session Status */
protected _requestSession?: RequestSession;

/** The client on this scope */
protected _client?: Client;

// NOTE: Any field which gets added here should get added not only to the constructor but also to the `clone` method.

public constructor() {
Expand Down Expand Up @@ -144,10 +148,25 @@ export class Scope implements ScopeInterface {
newScope._attachments = [...this._attachments];
newScope._sdkProcessingMetadata = { ...this._sdkProcessingMetadata };
newScope._propagationContext = { ...this._propagationContext };
newScope._client = this._client;

return newScope;
}

/** Update the client on the scope. */
public setClient(client: Client | undefined): void {
this._client = client;
}

/**
* Get the client assigned to this scope.
*
* It is generally recommended to use the global function `Sentry.getClient()` instead, unless you know what you are doing.
*/
public getClient(): Client | undefined {
return this._client;
}

/**
* Add internal on change listener. Used for sub SDKs that need to store the scope.
* @hidden
Expand Down
29 changes: 27 additions & 2 deletions packages/core/test/lib/scope.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Attachment, Breadcrumb } from '@sentry/types';
import type { Attachment, Breadcrumb, Client } from '@sentry/types';
import { applyScopeDataToEvent } from '../../src';
import { Scope, getGlobalScope, setGlobalScope } from '../../src/scope';

describe('Unit | Scope', () => {
describe('Scope', () => {
beforeEach(() => {
setGlobalScope(undefined);
});
Expand Down Expand Up @@ -187,4 +187,29 @@ describe('Unit | Scope', () => {
});
/* eslint-enable deprecation/deprecation */
});

describe('setClient() and getClient()', () => {
it('allows storing and retrieving client objects', () => {
const fakeClient = {} as Client;
const scope = new Scope();
scope.setClient(fakeClient);
expect(scope.getClient()).toBe(fakeClient);
});

it('defaults to not having a client', () => {
const scope = new Scope();
expect(scope.getClient()).toBeUndefined();
});
});

describe('.clone()', () => {
it('will clone a client on the scope', () => {
const fakeClient = {} as Client;
const scope = new Scope();
scope.setClient(fakeClient);

const clonedScope = scope.clone();
expect(clonedScope.getClient()).toBe(fakeClient);
});
});
});
3 changes: 0 additions & 3 deletions packages/node-experimental/src/sdk/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type {
Attachment,
Breadcrumb,
Client,
Contexts,
Event,
EventHint,
Expand Down Expand Up @@ -36,8 +35,6 @@ export interface Scope extends BaseScope {
isolationScope: typeof this | undefined;
// @ts-expect-error typeof this is what we want here
clone(scope?: Scope): typeof this;
setClient(client: Client): void;
getClient(): Client | undefined;
captureException(exception: unknown, hint?: EventHint): string;
captureMessage(
message: string,
Expand Down
13 changes: 13 additions & 0 deletions packages/types/src/scope.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Attachment } from './attachment';
import type { Breadcrumb } from './breadcrumb';
import type { Client } from './client';
import type { Context, Contexts } from './context';
import type { EventProcessor } from './eventprocessor';
import type { Extra, Extras } from './extra';
Expand Down Expand Up @@ -47,6 +48,18 @@ export interface ScopeData {
* Holds additional event information. {@link Scope.applyToEvent} will be called by the client before an event is sent.
*/
export interface Scope {
/**
* Update the client on the scope.
*/
setClient(client: Client | undefined): void;

/**
* Get the client assigned to this scope.
*
* It is generally recommended to use the global function `Sentry.getClient()` instead, unless you know what you are doing.
*/
getClient(): Client | undefined;

/** Add new event processor that will be called after {@link applyToEvent}. */
addEventProcessor(callback: EventProcessor): this;

Expand Down