Skip to content

Commit

Permalink
feat(core): Add setClient() and getClient() to Scope (#10055)
Browse files Browse the repository at this point in the history
  • Loading branch information
lforst committed Jan 4, 2024
1 parent 5462b04 commit 59ffba3
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 9 deletions.
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

0 comments on commit 59ffba3

Please sign in to comment.