From 3ca3fe57e371123f0c4a5eb0d16e3a4ff006348f Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Mon, 15 Jan 2024 17:55:04 +0100 Subject: [PATCH 1/2] feat(core): Deprecate `hub.bindClient()` & `makeMain()` Instead, users should use `setCurrentClient()` & `client.init()`. --- MIGRATION.md | 7 +- docs/v8-initializing.md | 65 ++++++++++++++ packages/astro/src/index.server.ts | 2 + packages/browser/src/exports.ts | 3 + packages/browser/test/unit/index.test.ts | 20 +++-- .../unit/integrations/breadcrumbs.test.ts | 20 +---- .../test/unit/profiling/hubextensions.test.ts | 1 + packages/bun/src/index.ts | 2 + .../bun/test/integrations/bunserver.test.ts | 1 + packages/core/src/hub.ts | 10 ++- packages/core/src/index.ts | 3 +- packages/core/src/sdk.ts | 29 +++++- packages/core/test/lib/exports.test.ts | 2 + packages/core/test/lib/integration.test.ts | 2 + .../test/lib/integrations/metadata.test.ts | 10 +-- .../test/lib/integrations/requestdata.test.ts | 6 +- .../tracing/dynamicSamplingContext.test.ts | 2 +- packages/core/test/lib/tracing/errors.test.ts | 1 + packages/core/test/lib/tracing/trace.test.ts | 2 + packages/deno/src/index.ts | 2 + .../unit/util/prepareFeedbackEvent.test.ts | 13 ++- packages/hub/src/index.ts | 1 + packages/node/src/index.ts | 2 + packages/node/test/async/domain.test.ts | 8 +- packages/node/test/async/hooks.test.ts | 19 +++- packages/node/test/handlers.test.ts | 60 +++++++------ packages/node/test/index.test.ts | 43 ++++++--- packages/node/test/integrations/http.test.ts | 88 +++++-------------- .../test/integrations/requestdata.test.ts | 7 +- .../node/test/integrations/undici.test.ts | 12 ++- .../test/propagator.test.ts | 1 + .../test/spanprocessor.test.ts | 5 ++ .../test/custom/hubextensions.test.ts | 4 +- .../test/custom/transaction.test.ts | 17 ++-- .../opentelemetry/test/propagator.test.ts | 1 + .../test/utils/setupEventContextTrace.test.ts | 1 + packages/react/test/errorboundary.test.tsx | 17 ++-- packages/remix/src/index.server.ts | 2 + .../test/unit/util/prepareReplayEvent.test.ts | 7 +- packages/serverless/src/index.ts | 2 + packages/sveltekit/src/server/index.ts | 2 + packages/sveltekit/test/server/handle.test.ts | 1 + .../test/browser/backgroundtab.test.ts | 1 + .../test/browser/browsertracing.test.ts | 10 ++- .../test/browser/request.test.ts | 9 +- packages/types/src/hub.ts | 2 + packages/vercel-edge/src/index.ts | 2 + packages/vue/test/errorHandler.test.ts | 4 +- 48 files changed, 346 insertions(+), 185 deletions(-) create mode 100644 docs/v8-initializing.md diff --git a/MIGRATION.md b/MIGRATION.md index be62a01187f9..61807fee0dfe 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -10,7 +10,12 @@ npx @sentry/migr8@latest This will let you select which updates to run, and automatically update your code. Make sure to still review all code changes! -## Deprecated `Transaction` integration +## Deprecate `hub.bindClient()` and `makeMain()` + +Instead, either directly use `initAndBind()`, or the new APIs `setCurrentClient()` and `client.init()`. See +[Initializing the SDK in v8](./docs/v8-initializing.md) for more details. + +## Deprecate `Transaction` integration This pluggable integration from `@sentry/integrations` will be removed in v8. It was already undocumented and is not necessary for the SDK to work as expected. diff --git a/docs/v8-initializing.md b/docs/v8-initializing.md new file mode 100644 index 000000000000..238f02aa1bf9 --- /dev/null +++ b/docs/v8-initializing.md @@ -0,0 +1,65 @@ +# Initializing the SDK in v8 + +In v8, manual initialization of the SDK will work as follows. + +## Classic initialization + +```ts +import * as Sentry from '@sentry/browser'; + +Sentry.init({ + dsn: 'xxx', +}); +``` + +This will initialize the SDK with all defaults & make it the currently active Sentry instance. This will continue to use +the existing global, isolation & current scope, and just bind the client to it. + +## Using multiple clients in Node + +In an environment with multiple execution contexts (e.g. Node), you can setup multiple clients that are active for +different contexts, like this: + +```js +import * as Sentry from '@sentry/browser'; + +// Sets up the _default_ client +Sentry.init({ + dsn: 'xxx', +}); + +// One execution context with client A +Sentry.withScope(() => { + const clientA = new Client(); + Sentry.setCurrentClient(clientA); // binds this client to the current execution context only! + clientA.init(); +}); + +// One execution context with client B +Sentry.withScope(() => { + const clientB = new Client(); + Sentry.setCurrentClient(clientB); // binds this client to the current execution context only! + clientB.init(); +}); +``` + +## Using multiple clients in Browser + +In environments without execution contexts, like the browser, you can only ever have a single active client. You can, +however, create further clients and use them manually: + +```js +// Default client - this is used everywhere +Sentry.init({ + dsn: 'xxx', +}); + +// Setup a manual client +const clientA = new Client(); +const scope = new Scope(); +scope.setClient(clientA); +// You can capture exceptions manually for this client like this: +scope.captureException(); +``` + +This is also necessary e.g. if you have a browser extension or some other code that runs in a shared environment. diff --git a/packages/astro/src/index.server.ts b/packages/astro/src/index.server.ts index a7eab7f0fbe9..4358fa6ab4ea 100644 --- a/packages/astro/src/index.server.ts +++ b/packages/astro/src/index.server.ts @@ -31,7 +31,9 @@ export { getGlobalScope, getIsolationScope, Hub, + // eslint-disable-next-line deprecation/deprecation makeMain, + setCurrentClient, Scope, // eslint-disable-next-line deprecation/deprecation startTransaction, diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index f0e167db50b4..116f06719fee 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -43,7 +43,10 @@ export { Hub, // eslint-disable-next-line deprecation/deprecation lastEventId, + // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line deprecation/deprecation makeMain, + setCurrentClient, Scope, // eslint-disable-next-line deprecation/deprecation startTransaction, diff --git a/packages/browser/test/unit/index.test.ts b/packages/browser/test/unit/index.test.ts index 80b0da9b7c64..3a9e06be9ec6 100644 --- a/packages/browser/test/unit/index.test.ts +++ b/packages/browser/test/unit/index.test.ts @@ -3,6 +3,7 @@ import type { WrappedFunction } from '@sentry/types'; import * as utils from '@sentry/utils'; import type { Event } from '../../src'; +import { setCurrentClient } from '../../src'; import { BrowserClient, Integrations, @@ -14,7 +15,6 @@ import { captureMessage, flush, getClient, - getCurrentHub, getCurrentScope, init, showReportDialog, @@ -86,7 +86,7 @@ describe('SentryBrowser', () => { const client = new BrowserClient(options); it('uses the user on the scope', () => { getCurrentScope().setUser(EX_USER); - getCurrentHub().bindClient(client); + setCurrentClient(client); // eslint-disable-next-line deprecation/deprecation showReportDialog(); @@ -100,7 +100,7 @@ describe('SentryBrowser', () => { it('prioritizes options user over scope user', () => { getCurrentScope().setUser(EX_USER); - getCurrentHub().bindClient(client); + setCurrentClient(client); const DIALOG_OPTION_USER = { email: 'option@example.com' }; // eslint-disable-next-line deprecation/deprecation @@ -216,7 +216,7 @@ describe('SentryBrowser', () => { }, dsn, }); - getCurrentHub().bindClient(new BrowserClient(options)); + setCurrentClient(new BrowserClient(options)); captureMessage('test'); }); @@ -230,7 +230,7 @@ describe('SentryBrowser', () => { }, dsn, }); - getCurrentHub().bindClient(new BrowserClient(options)); + setCurrentClient(new BrowserClient(options)); captureEvent({ message: 'event' }); }); @@ -243,7 +243,7 @@ describe('SentryBrowser', () => { }, dsn, }); - getCurrentHub().bindClient(new BrowserClient(options)); + setCurrentClient(new BrowserClient(options)); captureEvent({ message: 'event' }); }); @@ -254,7 +254,7 @@ describe('SentryBrowser', () => { dsn, integrations: [], }); - getCurrentHub().bindClient(new BrowserClient(options)); + setCurrentClient(new BrowserClient(options)); captureMessage('event222'); captureMessage('event222'); @@ -271,7 +271,9 @@ describe('SentryBrowser', () => { dsn, integrations: [new Integrations.InboundFilters({ ignoreErrors: ['capture'] })], }); - getCurrentHub().bindClient(new BrowserClient(options)); + const client = new BrowserClient(options); + setCurrentClient(client); + client.init(); captureMessage('capture'); @@ -405,7 +407,7 @@ describe('wrap()', () => { }, dsn, }); - getCurrentHub().bindClient(new BrowserClient(options)); + setCurrentClient(new BrowserClient(options)); try { // eslint-disable-next-line deprecation/deprecation diff --git a/packages/browser/test/unit/integrations/breadcrumbs.test.ts b/packages/browser/test/unit/integrations/breadcrumbs.test.ts index e87454737482..c2aea2ee170f 100644 --- a/packages/browser/test/unit/integrations/breadcrumbs.test.ts +++ b/packages/browser/test/unit/integrations/breadcrumbs.test.ts @@ -1,30 +1,18 @@ import * as SentryCore from '@sentry/core'; -import type { Client } from '@sentry/types'; -import { Breadcrumbs, BrowserClient, Hub, flush } from '../../../src'; +import { Breadcrumbs, BrowserClient, flush } from '../../../src'; import { getDefaultBrowserClientOptions } from '../helper/browser-client-options'; -const hub = new Hub(); -let client: Client | undefined; - -jest.mock('@sentry/core', () => { - const original = jest.requireActual('@sentry/core'); - return { - ...original, - getCurrentHub: () => hub, - getClient: () => client, - }; -}); - describe('Breadcrumbs', () => { it('Should add sentry breadcrumb', async () => { - client = new BrowserClient({ + const client = new BrowserClient({ ...getDefaultBrowserClientOptions(), dsn: 'https://username@domain/123', integrations: [new Breadcrumbs()], }); - SentryCore.getCurrentHub().bindClient(client); + SentryCore.setCurrentClient(client); + client.init(); const addBreadcrumbSpy = jest.spyOn(SentryCore, 'addBreadcrumb').mockImplementation(() => {}); diff --git a/packages/browser/test/unit/profiling/hubextensions.test.ts b/packages/browser/test/unit/profiling/hubextensions.test.ts index 30b7769e836d..552b71ca9b81 100644 --- a/packages/browser/test/unit/profiling/hubextensions.test.ts +++ b/packages/browser/test/unit/profiling/hubextensions.test.ts @@ -47,6 +47,7 @@ describe('BrowserProfilingIntegration', () => { }, }; + // eslint-disable-next-line deprecation/deprecation hub.bindClient(client); }); diff --git a/packages/bun/src/index.ts b/packages/bun/src/index.ts index 83b4b90ab01b..cc41d3e4f61e 100644 --- a/packages/bun/src/index.ts +++ b/packages/bun/src/index.ts @@ -50,7 +50,9 @@ export { Hub, // eslint-disable-next-line deprecation/deprecation lastEventId, + // eslint-disable-next-line deprecation/deprecation makeMain, + setCurrentClient, runWithAsyncContext, Scope, // eslint-disable-next-line deprecation/deprecation diff --git a/packages/bun/test/integrations/bunserver.test.ts b/packages/bun/test/integrations/bunserver.test.ts index 286d30749dc1..bd62881b8ccf 100644 --- a/packages/bun/test/integrations/bunserver.test.ts +++ b/packages/bun/test/integrations/bunserver.test.ts @@ -20,6 +20,7 @@ describe('Bun Serve Integration', () => { const options = getDefaultBunClientOptions({ tracesSampleRate: 1, debug: true }); client = new BunClient(options); hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); }); diff --git a/packages/core/src/hub.ts b/packages/core/src/hub.ts index 815a55293516..85d80786cfeb 100644 --- a/packages/core/src/hub.ts +++ b/packages/core/src/hub.ts @@ -147,6 +147,7 @@ export class Hub implements HubInterface { this._stack = [{ scope: assignedScope }]; if (client) { + // eslint-disable-next-line deprecation/deprecation this.bindClient(client); } @@ -166,7 +167,10 @@ export class Hub implements HubInterface { } /** - * @inheritDoc + * This binds the given client to the current scope. + * @param client An SDK client (client) instance. + * + * @deprecated Use `initAndBind()` directly, or `setCurrentClient()` and/or `client.init()` instead. */ public bindClient(client?: Client): void { // eslint-disable-next-line deprecation/deprecation @@ -488,10 +492,12 @@ export class Hub implements HubInterface { * @inheritDoc */ public run(callback: (hub: Hub) => void): void { + // eslint-disable-next-line deprecation/deprecation const oldHub = makeMain(this); try { callback(this); } finally { + // eslint-disable-next-line deprecation/deprecation makeMain(oldHub); } } @@ -690,6 +696,8 @@ export function getMainCarrier(): Carrier { * Replaces the current main hub with the passed one on the global object * * @returns The old replaced hub + * + * @deprecated Use `setCurrentClient()` instead. */ export function makeMain(hub: Hub): Hub { const registry = getMainCarrier(); diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 026f9b5164d9..6ca0444b6c34 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -41,6 +41,7 @@ export { getIsolationScope, getHubFromCarrier, Hub, + // eslint-disable-next-line deprecation/deprecation makeMain, getMainCarrier, runWithAsyncContext, @@ -59,7 +60,7 @@ export { export { getEnvelopeEndpointWithUrlEncodedAuth, getReportDialogEndpoint } from './api'; export { BaseClient, addEventProcessor } from './baseclient'; export { ServerRuntimeClient } from './server-runtime-client'; -export { initAndBind } from './sdk'; +export { initAndBind, setCurrentClient } from './sdk'; export { createTransport } from './transports/base'; export { makeOfflineTransport } from './transports/offline'; export { makeMultiplexedTransport } from './transports/multiplexed'; diff --git a/packages/core/src/sdk.ts b/packages/core/src/sdk.ts index 529f425746a7..51757d293f00 100644 --- a/packages/core/src/sdk.ts +++ b/packages/core/src/sdk.ts @@ -35,5 +35,32 @@ export function initAndBind( scope.update(options.initialScope); const client = new clientClass(options); - hub.bindClient(client); + setCurrentClient(client); + initializeClient(client); +} + +/** + * Make the given client the current client. + */ +export function setCurrentClient(client: Client): void { + const hub = getCurrentHub(); + // eslint-disable-next-line deprecation/deprecation + const top = hub.getStackTop(); + top.client = client; + top.scope.setClient(client); +} + +/** + * Initialize the client for the current scope. + * Make sure to call this after `setCurrentClient()`. + */ +function initializeClient(client: Client): void { + if (client.init) { + client.init(); + // TODO v8: Remove this fallback + // eslint-disable-next-line deprecation/deprecation + } else if (client.setupIntegrations) { + // eslint-disable-next-line deprecation/deprecation + client.setupIntegrations(); + } } diff --git a/packages/core/test/lib/exports.test.ts b/packages/core/test/lib/exports.test.ts index e4512b7f6732..f0975065f12e 100644 --- a/packages/core/test/lib/exports.test.ts +++ b/packages/core/test/lib/exports.test.ts @@ -30,6 +30,7 @@ describe('withScope', () => { beforeEach(() => { const client = getTestClient(); const hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); }); @@ -171,6 +172,7 @@ describe('session APIs', () => { beforeEach(() => { const client = getTestClient(); const hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); }); diff --git a/packages/core/test/lib/integration.test.ts b/packages/core/test/lib/integration.test.ts index 829ef4de991b..25eef6226b93 100644 --- a/packages/core/test/lib/integration.test.ts +++ b/packages/core/test/lib/integration.test.ts @@ -618,6 +618,7 @@ describe('addIntegration', () => { const client = getTestClient(); const hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); const integration = new CustomIntegration(); @@ -635,6 +636,7 @@ describe('addIntegration', () => { } const hub = new Hub(); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); const integration = new CustomIntegration(); diff --git a/packages/core/test/lib/integrations/metadata.test.ts b/packages/core/test/lib/integrations/metadata.test.ts index 7e8bfcea9fa4..1a20ffaee73d 100644 --- a/packages/core/test/lib/integrations/metadata.test.ts +++ b/packages/core/test/lib/integrations/metadata.test.ts @@ -2,7 +2,7 @@ import { TextDecoder, TextEncoder } from 'util'; import type { Event } from '@sentry/types'; import { GLOBAL_OBJ, createStackParser, nodeStackLineParser, parseEnvelope } from '@sentry/utils'; -import { ModuleMetadata, createTransport, getCurrentHub } from '../../../src'; +import { ModuleMetadata, captureException, createTransport, setCurrentClient } from '../../../src'; import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; const stackParser = createStackParser(nodeStackLineParser()); @@ -59,9 +59,9 @@ describe('ModuleMetadata integration', () => { }); const client = new TestClient(options); - const hub = getCurrentHub(); - hub.bindClient(client); - // eslint-disable-next-line deprecation/deprecation - hub.captureException(new Error('Some error')); + setCurrentClient(client); + client.init(); + + captureException(new Error('Some error')); }); }); diff --git a/packages/core/test/lib/integrations/requestdata.test.ts b/packages/core/test/lib/integrations/requestdata.test.ts index fe80c2ffd623..37d624d6e757 100644 --- a/packages/core/test/lib/integrations/requestdata.test.ts +++ b/packages/core/test/lib/integrations/requestdata.test.ts @@ -1,6 +1,7 @@ import type { IncomingMessage } from 'http'; import type { RequestDataIntegrationOptions } from '@sentry/core'; -import { RequestData, getCurrentHub } from '@sentry/core'; +import { setCurrentClient } from '@sentry/core'; +import { RequestData } from '@sentry/core'; import type { Event, EventProcessor } from '@sentry/types'; import * as sentryUtils from '@sentry/utils'; @@ -27,7 +28,8 @@ function initWithRequestDataIntegrationOptions(integrationOptions: RequestDataIn }), ); - getCurrentHub().bindClient(client); + setCurrentClient(client); + client.init(); const eventProcessors = client['_eventProcessors'] as EventProcessor[]; const eventProcessor = eventProcessors.find(processor => processor.id === 'RequestData'); diff --git a/packages/core/test/lib/tracing/dynamicSamplingContext.test.ts b/packages/core/test/lib/tracing/dynamicSamplingContext.test.ts index 91158d36ff01..01c99e3b87fd 100644 --- a/packages/core/test/lib/tracing/dynamicSamplingContext.test.ts +++ b/packages/core/test/lib/tracing/dynamicSamplingContext.test.ts @@ -10,7 +10,7 @@ describe('getDynamicSamplingContextFromSpan', () => { const options = getDefaultTestClientOptions({ tracesSampleRate: 1.0, release: '1.0.1' }); const client = new TestClient(options); hub = new Hub(client); - hub.bindClient(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); addTracingExtensions(); }); diff --git a/packages/core/test/lib/tracing/errors.test.ts b/packages/core/test/lib/tracing/errors.test.ts index d2714901d39e..b1711f860679 100644 --- a/packages/core/test/lib/tracing/errors.test.ts +++ b/packages/core/test/lib/tracing/errors.test.ts @@ -35,6 +35,7 @@ describe('registerErrorHandlers()', () => { mockAddGlobalUnhandledRejectionInstrumentationHandler.mockClear(); const options = getDefaultBrowserClientOptions({ enableTracing: true }); const hub = new Hub(new BrowserClient(options)); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); }); diff --git a/packages/core/test/lib/tracing/trace.test.ts b/packages/core/test/lib/tracing/trace.test.ts index c8751c90e89d..4de432cbf0b3 100644 --- a/packages/core/test/lib/tracing/trace.test.ts +++ b/packages/core/test/lib/tracing/trace.test.ts @@ -27,6 +27,7 @@ describe('startSpan', () => { const options = getDefaultTestClientOptions({ tracesSampleRate: 0.0 }); client = new TestClient(options); hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); }); @@ -343,6 +344,7 @@ describe('continueTrace', () => { const options = getDefaultTestClientOptions({ tracesSampleRate: 0.0 }); client = new TestClient(options); hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); }); diff --git a/packages/deno/src/index.ts b/packages/deno/src/index.ts index cf216aa033cb..8d9b90471a7e 100644 --- a/packages/deno/src/index.ts +++ b/packages/deno/src/index.ts @@ -49,7 +49,9 @@ export { Hub, // eslint-disable-next-line deprecation/deprecation lastEventId, + // eslint-disable-next-line deprecation/deprecation makeMain, + setCurrentClient, runWithAsyncContext, Scope, // eslint-disable-next-line deprecation/deprecation diff --git a/packages/feedback/test/unit/util/prepareFeedbackEvent.test.ts b/packages/feedback/test/unit/util/prepareFeedbackEvent.test.ts index 21e8326cec2d..fa90083d703f 100644 --- a/packages/feedback/test/unit/util/prepareFeedbackEvent.test.ts +++ b/packages/feedback/test/unit/util/prepareFeedbackEvent.test.ts @@ -1,20 +1,19 @@ -import type { Hub, Scope } from '@sentry/core'; +import type { Scope } from '@sentry/core'; +import { setCurrentClient } from '@sentry/core'; import { getCurrentScope } from '@sentry/core'; -import { getCurrentHub } from '@sentry/core'; -import type { Client, FeedbackEvent } from '@sentry/types'; +import type { FeedbackEvent } from '@sentry/types'; import { prepareFeedbackEvent } from '../../../src/util/prepareFeedbackEvent'; import { TestClient, getDefaultClientOptions } from '../../utils/TestClient'; describe('Unit | util | prepareFeedbackEvent', () => { - let hub: Hub; - let client: Client; + let client: TestClient; let scope: Scope; beforeEach(() => { - hub = getCurrentHub(); client = new TestClient(getDefaultClientOptions()); - hub.bindClient(client); + setCurrentClient(client); + client.init(); scope = getCurrentScope(); }); diff --git a/packages/hub/src/index.ts b/packages/hub/src/index.ts index 579b5b932e7e..8f331511aa84 100644 --- a/packages/hub/src/index.ts +++ b/packages/hub/src/index.ts @@ -62,6 +62,7 @@ export const getMainCarrier = getMainCarrierCore; /** * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. */ +// eslint-disable-next-line deprecation/deprecation export const makeMain = makeMainCore; /** diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 6d856d14fc39..82561e363c26 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -49,7 +49,9 @@ export { Hub, // eslint-disable-next-line deprecation/deprecation lastEventId, + // eslint-disable-next-line deprecation/deprecation makeMain, + setCurrentClient, runWithAsyncContext, Scope, // eslint-disable-next-line deprecation/deprecation diff --git a/packages/node/test/async/domain.test.ts b/packages/node/test/async/domain.test.ts index 96f19386e63f..f5323e4bca91 100644 --- a/packages/node/test/async/domain.test.ts +++ b/packages/node/test/async/domain.test.ts @@ -1,10 +1,16 @@ -import type { Hub } from '@sentry/core'; +import { Hub, makeMain } from '@sentry/core'; import { getIsolationScope, withIsolationScope } from '@sentry/core'; import { getCurrentHub, runWithAsyncContext, setAsyncContextStrategy } from '@sentry/core'; import { setDomainAsyncContextStrategy } from '../../src/async/domain'; describe('setDomainAsyncContextStrategy()', () => { + beforeEach(() => { + const hub = new Hub(); + // eslint-disable-next-line deprecation/deprecation + makeMain(hub); + }); + afterEach(() => { // clear the strategy setAsyncContextStrategy(undefined); diff --git a/packages/node/test/async/hooks.test.ts b/packages/node/test/async/hooks.test.ts index f42619839043..991b7456d6fa 100644 --- a/packages/node/test/async/hooks.test.ts +++ b/packages/node/test/async/hooks.test.ts @@ -1,12 +1,23 @@ -import type { Hub } from '@sentry/core'; -import { getIsolationScope } from '@sentry/core'; -import { withIsolationScope } from '@sentry/core'; -import { getCurrentHub, runWithAsyncContext, setAsyncContextStrategy } from '@sentry/core'; +import { + Hub, + getCurrentHub, + getIsolationScope, + makeMain, + runWithAsyncContext, + setAsyncContextStrategy, + withIsolationScope, +} from '@sentry/core'; import { setHooksAsyncContextStrategy } from '../../src/async/hooks'; import { conditionalTest } from '../utils'; conditionalTest({ min: 12 })('setHooksAsyncContextStrategy()', () => { + beforeEach(() => { + const hub = new Hub(); + // eslint-disable-next-line deprecation/deprecation + makeMain(hub); + }); + afterEach(() => { // clear the strategy setAsyncContextStrategy(undefined); diff --git a/packages/node/test/handlers.test.ts b/packages/node/test/handlers.test.ts index 574c4addc27b..1b12a972d7d3 100644 --- a/packages/node/test/handlers.test.ts +++ b/packages/node/test/handlers.test.ts @@ -1,7 +1,15 @@ import * as http from 'http'; -import type { Hub } from '@sentry/core'; import * as sentryCore from '@sentry/core'; -import { Transaction, getClient, getCurrentScope, setAsyncContextStrategy } from '@sentry/core'; +import { + Hub, + Scope, + Transaction, + getClient, + getCurrentScope, + makeMain, + setAsyncContextStrategy, + spanToJSON, +} from '@sentry/core'; import type { Event, PropagationContext } from '@sentry/types'; import { SentryError } from '@sentry/utils'; @@ -58,7 +66,7 @@ describe('requestHandler', () => { it('autoSessionTracking is enabled, sets requestSession status to ok, when handling a request', () => { const options = getDefaultNodeClientOptions({ autoSessionTracking: true, release: '1.2' }); client = new NodeClient(options); - const hub = new sentryCore.Hub(client); + const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); mockAsyncContextStrategy(() => hub); @@ -72,7 +80,7 @@ describe('requestHandler', () => { it('autoSessionTracking is disabled, does not set requestSession, when handling a request', () => { const options = getDefaultNodeClientOptions({ autoSessionTracking: false, release: '1.2' }); client = new NodeClient(options); - const hub = new sentryCore.Hub(client); + const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); mockAsyncContextStrategy(() => hub); @@ -86,7 +94,7 @@ describe('requestHandler', () => { it('autoSessionTracking is enabled, calls _captureRequestSession, on response finish', done => { const options = getDefaultNodeClientOptions({ autoSessionTracking: true, release: '1.2' }); client = new NodeClient(options); - const hub = new sentryCore.Hub(client); + const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); mockAsyncContextStrategy(() => hub); @@ -108,7 +116,7 @@ describe('requestHandler', () => { it('autoSessionTracking is disabled, does not call _captureRequestSession, on response finish', done => { const options = getDefaultNodeClientOptions({ autoSessionTracking: false, release: '1.2' }); client = new NodeClient(options); - const hub = new sentryCore.Hub(client); + const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); mockAsyncContextStrategy(() => hub); @@ -154,7 +162,7 @@ describe('requestHandler', () => { }); it('stores request and request data options in `sdkProcessingMetadata`', () => { - const hub = new sentryCore.Hub(new NodeClient(getDefaultNodeClientOptions())); + const hub = new Hub(new NodeClient(getDefaultNodeClientOptions())); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); mockAsyncContextStrategy(() => hub); @@ -182,7 +190,7 @@ describe('tracingHandler', () => { const sentryTracingMiddleware = tracingHandler(); - let hub: sentryCore.Hub, req: http.IncomingMessage, res: http.ServerResponse, next: () => undefined; + let hub: Hub, req: http.IncomingMessage, res: http.ServerResponse, next: () => undefined; function createNoOpSpy() { const noop = { noop: () => undefined }; // this is wrapped in an object so jest can spy on it @@ -190,8 +198,9 @@ describe('tracingHandler', () => { } beforeEach(() => { - hub = new sentryCore.Hub(new NodeClient(getDefaultNodeClientOptions({ tracesSampleRate: 1.0 }))); - sentryCore.makeMain(hub); + hub = new Hub(new NodeClient(getDefaultNodeClientOptions({ tracesSampleRate: 1.0 }))); + // eslint-disable-next-line deprecation/deprecation + makeMain(hub); mockAsyncContextStrategy(() => hub); req = { @@ -312,7 +321,7 @@ describe('tracingHandler', () => { it('extracts request data for sampling context', () => { const tracesSampler = jest.fn(); const options = getDefaultNodeClientOptions({ tracesSampler }); - const hub = new sentryCore.Hub(new NodeClient(options)); + const hub = new Hub(new NodeClient(options)); mockAsyncContextStrategy(() => hub); hub.run(() => { @@ -334,7 +343,7 @@ describe('tracingHandler', () => { it('puts its transaction on the scope', () => { const options = getDefaultNodeClientOptions({ tracesSampleRate: 1.0 }); - const hub = new sentryCore.Hub(new NodeClient(options)); + const hub = new Hub(new NodeClient(options)); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); mockAsyncContextStrategy(() => hub); @@ -376,9 +385,7 @@ describe('tracingHandler', () => { expect(transaction.status).toBe('ok'); // eslint-disable-next-line deprecation/deprecation expect(transaction.tags).toEqual(expect.objectContaining({ 'http.status_code': '200' })); - expect(sentryCore.spanToJSON(transaction).data).toEqual( - expect.objectContaining({ 'http.response.status_code': 200 }), - ); + expect(spanToJSON(transaction).data).toEqual(expect.objectContaining({ 'http.response.status_code': 200 })); done(); }); }); @@ -464,7 +471,7 @@ describe('tracingHandler', () => { it('stores request in transaction metadata', () => { const options = getDefaultNodeClientOptions({ tracesSampleRate: 1.0 }); - const hub = new sentryCore.Hub(new NodeClient(options)); + const hub = new Hub(new NodeClient(options)); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); // eslint-disable-next-line deprecation/deprecation @@ -473,7 +480,7 @@ describe('tracingHandler', () => { sentryTracingMiddleware(req, res, next); // eslint-disable-next-line deprecation/deprecation - const transaction = sentryCore.getCurrentScope().getTransaction(); + const transaction = getCurrentScope().getTransaction(); // eslint-disable-next-line deprecation/deprecation expect(transaction?.metadata.request).toEqual(req); @@ -522,7 +529,7 @@ describe('errorHandler()', () => { client.initSessionFlusher(); const scope = getCurrentScope(); - const hub = new sentryCore.Hub(client); + const hub = new Hub(client); jest.spyOn(client, '_captureRequestSession'); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -538,7 +545,7 @@ describe('errorHandler()', () => { client = new NodeClient(options); const scope = getCurrentScope(); - const hub = new sentryCore.Hub(client); + const hub = new Hub(client); jest.spyOn(client, '_captureRequestSession'); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -555,8 +562,8 @@ describe('errorHandler()', () => { // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); - const scope = new sentryCore.Scope(); - const hub = new sentryCore.Hub(client, scope); + const scope = new Scope(); + const hub = new Hub(client, scope); mockAsyncContextStrategy(() => hub); jest.spyOn(client, '_captureRequestSession'); @@ -577,8 +584,8 @@ describe('errorHandler()', () => { // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); - const scope = new sentryCore.Scope(); - const hub = new sentryCore.Hub(client, scope); + const scope = new Scope(); + const hub = new Hub(client, scope); jest.spyOn(client, '_captureRequestSession'); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -592,14 +599,15 @@ describe('errorHandler()', () => { const options = getDefaultNodeClientOptions({}); client = new NodeClient(options); - const hub = new sentryCore.Hub(client); + const hub = new Hub(client); mockAsyncContextStrategy(() => hub); - sentryCore.makeMain(hub); + // eslint-disable-next-line deprecation/deprecation + makeMain(hub); // `sentryErrorMiddleware` uses `withScope`, and we need access to the temporary scope it creates, so monkeypatch // `captureException` in order to examine the scope as it exists inside the `withScope` callback // eslint-disable-next-line deprecation/deprecation - hub.captureException = function (this: sentryCore.Hub, _exception: any) { + hub.captureException = function (this: Hub, _exception: any) { // eslint-disable-next-line deprecation/deprecation const scope = this.getScope(); expect((scope as any)._sdkProcessingMetadata.request).toEqual(req); diff --git a/packages/node/test/index.test.ts b/packages/node/test/index.test.ts index a5aa6e5cc699..4d54b042a117 100644 --- a/packages/node/test/index.test.ts +++ b/packages/node/test/index.test.ts @@ -1,4 +1,11 @@ -import { LinkedErrors, SDK_VERSION, getMainCarrier, initAndBind, runWithAsyncContext } from '@sentry/core'; +import { + LinkedErrors, + SDK_VERSION, + getMainCarrier, + initAndBind, + runWithAsyncContext, + setCurrentClient, +} from '@sentry/core'; import type { EventHint, Integration } from '@sentry/types'; import { GLOBAL_OBJ } from '@sentry/utils'; @@ -92,7 +99,8 @@ describe('SentryNode', () => { stackParser: defaultStackParser, }); const client = new NodeClient(options); - getCurrentHub().bindClient(client); + setCurrentClient(client); + client.init(); addBreadcrumb({ message: 'test1' }); addBreadcrumb({ message: 'test2' }); captureMessage('event'); @@ -128,7 +136,9 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options)); + const client = new NodeClient(options); + setCurrentClient(client); + client.init(); getCurrentScope().setTag('test', '1'); try { throw new Error('test'); @@ -153,7 +163,9 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options)); + const client = new NodeClient(options); + setCurrentClient(client); + client.init(); getCurrentScope().setTag('test', '1'); try { throw 'test string exception'; @@ -184,7 +196,8 @@ describe('SentryNode', () => { integrations: [new ContextLines()], }); const client = new NodeClient(options); - getCurrentHub().bindClient(client); + setCurrentClient(client); + client.init(); getCurrentScope().setTag('test', '1'); try { throw new Error('test'); @@ -224,7 +237,9 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options)); + const client = new NodeClient(options); + setCurrentClient(client); + client.init(); try { throw new Error('test'); } catch (e) { @@ -249,7 +264,9 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options)); + const client = new NodeClient(options); + setCurrentClient(client); + client.init(); captureMessage('test'); }); @@ -265,7 +282,9 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options)); + const client = new NodeClient(options); + setCurrentClient(client); + client.init(); captureEvent({ message: 'test event' }); }); @@ -285,7 +304,9 @@ describe('SentryNode', () => { runWithAsyncContext(() => { const hub = getCurrentHub(); - hub.bindClient(client); + setCurrentClient(client); + client.init(); + // eslint-disable-next-line deprecation/deprecation expect(getCurrentHub().getClient()).toBe(client); expect(getClient()).toBe(client); @@ -308,7 +329,9 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options)); + const client = new NodeClient(options); + setCurrentClient(client); + client.init(); try { // eslint-disable-next-line no-inner-declarations function testy(): void { diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts index 609ea80c5075..6a94d19a73f4 100644 --- a/packages/node/test/integrations/http.test.ts +++ b/packages/node/test/integrations/http.test.ts @@ -2,8 +2,7 @@ import * as http from 'http'; import * as https from 'https'; import type { Span } from '@sentry/core'; import { Transaction } from '@sentry/core'; -import { getClient, getCurrentScope, startInactiveSpan } from '@sentry/core'; -import * as sentryCore from '@sentry/core'; +import { getCurrentScope, makeMain, setUser, spanToJSON, startInactiveSpan } from '@sentry/core'; import { Hub, addTracingExtensions } from '@sentry/core'; import type { TransactionContext } from '@sentry/types'; import { TRACEPARENT_REGEXP, logger } from '@sentry/utils'; @@ -23,38 +22,21 @@ const originalHttpRequest = http.request; describe('tracing', () => { afterEach(() => { // eslint-disable-next-line deprecation/deprecation - sentryCore.getCurrentScope().setSpan(undefined); + getCurrentScope().setSpan(undefined); }); function createTransactionOnScope( customOptions: Partial = {}, customContext?: Partial, ) { - const options = getDefaultNodeClientOptions({ - dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012', - tracesSampleRate: 1.0, - integrations: [new HttpIntegration({ tracing: true })], - release: '1.0.0', - environment: 'production', - ...customOptions, - }); - const hub = new Hub(new NodeClient(options)); - sentryCore.makeMain(hub); + setupMockHub(customOptions); addTracingExtensions(); - // eslint-disable-next-line deprecation/deprecation - hub.getScope().setUser({ + setUser({ id: 'uid123', segment: 'segmentA', }); - jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'getCurrentScope').mockImplementation(() => hub.getScope()); - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'getActiveSpan').mockImplementation(() => hub.getScope().getSpan()); - jest.spyOn(sentryCore, 'getClient').mockReturnValue(getClient()); - const transaction = startInactiveSpan({ name: 'dogpark', traceId: '12312012123120121231201212312012', @@ -78,14 +60,10 @@ describe('tracing', () => { environment: 'production', ...customOptions, }); - const hub = new Hub(new NodeClient(options)); - jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'getCurrentScope').mockImplementation(() => hub.getScope()); + const client = new NodeClient(options); + const hub = new Hub(client); // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'getActiveSpan').mockImplementation(() => hub.getScope().getSpan()); - jest.spyOn(sentryCore, 'getClient').mockReturnValue(getClient()); - return hub; + makeMain(hub); } it("creates a span for each outgoing non-sentry request when there's a transaction on the scope", () => { @@ -99,7 +77,7 @@ describe('tracing', () => { expect(spans.length).toEqual(2); // our span is at index 1 because the transaction itself is at index 0 - expect(sentryCore.spanToJSON(spans[1]).description).toEqual('GET http://dogs.are.great/'); + expect(spanToJSON(spans[1]).description).toEqual('GET http://dogs.are.great/'); expect(spans[1].op).toEqual('http.client'); }); @@ -113,7 +91,7 @@ describe('tracing', () => { // only the transaction itself should be there expect(spans.length).toEqual(1); - expect(sentryCore.spanToJSON(spans[0]).description).toEqual('dogpark'); + expect(spanToJSON(spans[0]).description).toEqual('dogpark'); }); it('attaches the sentry-trace header to outgoing non-sentry requests', async () => { @@ -301,10 +279,10 @@ describe('tracing', () => { expect(spans.length).toEqual(2); // our span is at index 1 because the transaction itself is at index 0 - expect(sentryCore.spanToJSON(spans[1]).description).toEqual('GET http://dogs.are.great/spaniel'); + expect(spanToJSON(spans[1]).description).toEqual('GET http://dogs.are.great/spaniel'); expect(spans[1].op).toEqual('http.client'); - const spanAttributes = sentryCore.spanToJSON(spans[1]).data || {}; + const spanAttributes = spanToJSON(spans[1]).data || {}; expect(spanAttributes['http.method']).toEqual('GET'); expect(spanAttributes.url).toEqual('http://dogs.are.great/spaniel'); @@ -322,10 +300,10 @@ describe('tracing', () => { expect(spans.length).toEqual(2); - const spanAttributes = sentryCore.spanToJSON(spans[1]).data || {}; + const spanAttributes = spanToJSON(spans[1]).data || {}; // our span is at index 1 because the transaction itself is at index 0 - expect(sentryCore.spanToJSON(spans[1]).description).toEqual('GET http://dogs.are.great/spaniel'); + expect(spanToJSON(spans[1]).description).toEqual('GET http://dogs.are.great/spaniel'); expect(spans[1].op).toEqual('http.client'); expect(spanAttributes['http.method']).toEqual('GET'); expect(spanAttributes.url).toEqual('http://dogs.are.great/spaniel'); @@ -350,7 +328,7 @@ describe('tracing', () => { expect(spans.length).toEqual(2); // our span is at index 1 because the transaction itself is at index 0 - expect(sentryCore.spanToJSON(spans[1]).description).toEqual(`GET http://${redactedAuth}dogs.are.great/`); + expect(spanToJSON(spans[1]).description).toEqual(`GET http://${redactedAuth}dogs.are.great/`); }); describe('Tracing options', () => { @@ -371,18 +349,10 @@ describe('tracing', () => { ...customOptions, }); - const hub = new Hub(); - - jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'getCurrentScope').mockImplementation(() => hub.getScope()); - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'getActiveSpan').mockImplementation(() => hub.getScope().getSpan()); - jest.spyOn(sentryCore, 'getClient').mockReturnValue(getClient()); - const client = new NodeClient(options); - jest.spyOn(hub, 'getClient').mockImplementation(() => client); - hub.bindClient(client); + const hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation + makeMain(hub); return hub; } @@ -404,13 +374,6 @@ describe('tracing', () => { const hub = createHub({ shouldCreateSpanForRequest: () => false }); - jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'getCurrentScope').mockImplementation(() => hub.getScope()); - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'getActiveSpan').mockImplementation(() => hub.getScope().getSpan()); - jest.spyOn(sentryCore, 'getClient').mockReturnValue(getClient()); - httpIntegration.setupOnce( () => undefined, () => hub, @@ -516,13 +479,6 @@ describe('tracing', () => { const hub = createHub(); - jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'getCurrentScope').mockImplementation(() => hub.getScope()); - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'getActiveSpan').mockImplementation(() => hub.getScope().getSpan()); - jest.spyOn(sentryCore, 'getClient').mockReturnValue(getClient()); - httpIntegration.setupOnce( () => undefined, () => hub, @@ -619,11 +575,6 @@ describe('tracing', () => { describe('default protocols', () => { function captureBreadcrumb(key: string): Promise { - const hub = new Hub(); - jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); - // eslint-disable-next-line deprecation/deprecation - jest.spyOn(sentryCore, 'addBreadcrumb').mockImplementation((...rest) => hub.addBreadcrumb(...rest)); - let resolve: (value: Breadcrumb | PromiseLike) => void; const p = new Promise(r => { resolve = r; @@ -638,7 +589,10 @@ describe('default protocols', () => { return b; }, }); - hub.bindClient(new NodeClient(options)); + const client = new NodeClient(options); + const hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation + makeMain(hub); return p; } diff --git a/packages/node/test/integrations/requestdata.test.ts b/packages/node/test/integrations/requestdata.test.ts index 61f71873fff4..5d7f68f17ca6 100644 --- a/packages/node/test/integrations/requestdata.test.ts +++ b/packages/node/test/integrations/requestdata.test.ts @@ -1,8 +1,9 @@ import * as http from 'http'; import type { RequestDataIntegrationOptions } from '@sentry/core'; +import { setCurrentClient } from '@sentry/core'; import { applyScopeDataToEvent } from '@sentry/core'; import { getCurrentScope } from '@sentry/core'; -import { RequestData, getCurrentHub } from '@sentry/core'; +import { RequestData } from '@sentry/core'; import type { Event, EventProcessor, PolymorphicRequest } from '@sentry/types'; import * as sentryUtils from '@sentry/utils'; @@ -30,8 +31,8 @@ function initWithRequestDataIntegrationOptions(integrationOptions: RequestDataIn integrations: [requestDataIntegration], }), ); - - getCurrentHub().bindClient(client); + setCurrentClient(client); + client.init(); const eventProcessors = client['_eventProcessors'] as EventProcessor[]; const eventProcessor = eventProcessors.find(processor => processor.id === 'RequestData'); diff --git a/packages/node/test/integrations/undici.test.ts b/packages/node/test/integrations/undici.test.ts index 124a1504ba79..7705b988f721 100644 --- a/packages/node/test/integrations/undici.test.ts +++ b/packages/node/test/integrations/undici.test.ts @@ -1,5 +1,5 @@ import * as http from 'http'; -import { Transaction, getActiveSpan, getClient, getCurrentScope, startSpan } from '@sentry/core'; +import { Transaction, getActiveSpan, getClient, getCurrentScope, setCurrentClient, startSpan } from '@sentry/core'; import { spanToTraceHeader } from '@sentry/core'; import { Hub, makeMain, runWithAsyncContext } from '@sentry/core'; import type { fetch as FetchType } from 'undici'; @@ -36,6 +36,7 @@ const DEFAULT_OPTIONS = getDefaultNodeClientOptions({ beforeEach(() => { const client = new NodeClient(DEFAULT_OPTIONS); hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); }); @@ -281,7 +282,8 @@ conditionalTest({ min: 16 })('Undici integration', () => { // eslint-disable-next-line jest/no-disabled-tests it.skip('uses tracePropagationTargets', async () => { const client = new NodeClient({ ...DEFAULT_OPTIONS, tracePropagationTargets: ['/yes'] }); - hub.bindClient(client); + setCurrentClient(client); + client.init(); await startSpan({ name: 'outer-span' }, async outerSpan => { expect(outerSpan).toBeInstanceOf(Transaction); @@ -324,7 +326,8 @@ conditionalTest({ min: 16 })('Undici integration', () => { return breadcrumb; }, }); - hub.bindClient(client); + setCurrentClient(client); + client.init(); await fetch('http://localhost:18100', { method: 'POST' }); }); @@ -348,7 +351,8 @@ conditionalTest({ min: 16 })('Undici integration', () => { return breadcrumb; }, }); - hub.bindClient(client); + setCurrentClient(client); + client.init(); try { await fetch('http://a-url-that-no-exists.com'); diff --git a/packages/opentelemetry-node/test/propagator.test.ts b/packages/opentelemetry-node/test/propagator.test.ts index 22c686320e76..ddd4594c5157 100644 --- a/packages/opentelemetry-node/test/propagator.test.ts +++ b/packages/opentelemetry-node/test/propagator.test.ts @@ -48,6 +48,7 @@ describe('SentryPropagator', () => { }; // @ts-expect-error Use mock client for unit tests const hub: Hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); afterEach(() => { diff --git a/packages/opentelemetry-node/test/spanprocessor.test.ts b/packages/opentelemetry-node/test/spanprocessor.test.ts index 4f8e52a622ae..7eecb73ea8bb 100644 --- a/packages/opentelemetry-node/test/spanprocessor.test.ts +++ b/packages/opentelemetry-node/test/spanprocessor.test.ts @@ -47,6 +47,7 @@ describe('SentrySpanProcessor', () => { client = new NodeClient(DEFAULT_NODE_CLIENT_OPTIONS); hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); spanProcessor = new SentrySpanProcessor(); @@ -891,6 +892,7 @@ describe('SentrySpanProcessor', () => { }, }); hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); // Need to register the spanprocessor again @@ -937,6 +939,7 @@ describe('SentrySpanProcessor', () => { }, }); hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); const tracer = provider.getTracer('default'); @@ -983,6 +986,7 @@ describe('SentrySpanProcessor', () => { }); hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); // eslint-disable-next-line deprecation/deprecation @@ -994,6 +998,7 @@ describe('SentrySpanProcessor', () => { tracer.startActiveSpan('GET /users', parentOtelSpan => { tracer.startActiveSpan('SELECT * FROM users;', child => { + // eslint-disable-next-line deprecation/deprecation makeMain(newHub); child.end(); }); diff --git a/packages/opentelemetry/test/custom/hubextensions.test.ts b/packages/opentelemetry/test/custom/hubextensions.test.ts index 6e246763a92a..dea308d99f3a 100644 --- a/packages/opentelemetry/test/custom/hubextensions.test.ts +++ b/packages/opentelemetry/test/custom/hubextensions.test.ts @@ -1,3 +1,4 @@ +import { setCurrentClient } from '@sentry/core'; import { getCurrentHub } from '../../src/custom/hub'; import { addTracingExtensions } from '../../src/custom/hubextensions'; import { TestClient, getDefaultTestClientOptions } from '../helpers/TestClient'; @@ -9,7 +10,8 @@ describe('hubextensions', () => { it('startTransaction is noop', () => { const client = new TestClient(getDefaultTestClientOptions()); - getCurrentHub().bindClient(client); + setCurrentClient(client); + client.init(); addTracingExtensions(); const mockConsole = jest.spyOn(console, 'warn').mockImplementation(() => {}); diff --git a/packages/opentelemetry/test/custom/transaction.test.ts b/packages/opentelemetry/test/custom/transaction.test.ts index 5b1ccc5b8044..8626422e5d78 100644 --- a/packages/opentelemetry/test/custom/transaction.test.ts +++ b/packages/opentelemetry/test/custom/transaction.test.ts @@ -1,4 +1,4 @@ -import { spanToJSON } from '@sentry/core'; +import { setCurrentClient, spanToJSON } from '@sentry/core'; import { getCurrentHub } from '../../src/custom/hub'; import { OpenTelemetryScope } from '../../src/custom/scope'; import { OpenTelemetryTransaction, startTransaction } from '../../src/custom/transaction'; @@ -15,7 +15,8 @@ describe('NodeExperimentalTransaction', () => { const mockSend = jest.spyOn(client, 'captureEvent').mockImplementation(() => 'mocked'); const hub = getCurrentHub(); - hub.bindClient(client); + setCurrentClient(client); + client.init(); // eslint-disable-next-line deprecation/deprecation const transaction = new OpenTelemetryTransaction({ name: 'test', sampled: true }, hub); @@ -62,7 +63,8 @@ describe('NodeExperimentalTransaction', () => { const mockSend = jest.spyOn(client, 'captureEvent').mockImplementation(() => 'mocked'); const hub = getCurrentHub(); - hub.bindClient(client); + setCurrentClient(client); + client.init(); // eslint-disable-next-line deprecation/deprecation const transaction = new OpenTelemetryTransaction({ name: 'test', startTimestamp: 123456, sampled: true }, hub); @@ -87,7 +89,8 @@ describe('NodeExperimentalTransaction', () => { const mockSend = jest.spyOn(client, 'captureEvent').mockImplementation(() => 'mocked'); const hub = getCurrentHub(); - hub.bindClient(client); + setCurrentClient(client); + client.init(); // eslint-disable-next-line deprecation/deprecation const transaction = new OpenTelemetryTransaction({ name: 'test', startTimestamp: 123456, sampled: true }, hub); @@ -144,7 +147,8 @@ describe('startTranscation', () => { it('creates a NodeExperimentalTransaction', () => { const client = new TestClient(getDefaultTestClientOptions()); const hub = getCurrentHub(); - hub.bindClient(client); + setCurrentClient(client); + client.init(); const transaction = startTransaction(hub, { name: 'test' }); @@ -171,7 +175,8 @@ describe('startTranscation', () => { it('allows to pass data to transaction', () => { const client = new TestClient(getDefaultTestClientOptions()); const hub = getCurrentHub(); - hub.bindClient(client); + setCurrentClient(client); + client.init(); const transaction = startTransaction(hub, { name: 'test', diff --git a/packages/opentelemetry/test/propagator.test.ts b/packages/opentelemetry/test/propagator.test.ts index 9b4cdb21d5aa..1663021b6224 100644 --- a/packages/opentelemetry/test/propagator.test.ts +++ b/packages/opentelemetry/test/propagator.test.ts @@ -42,6 +42,7 @@ describe('SentryPropagator', () => { }; // @ts-expect-error Use mock client for unit tests const hub: Hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); describe('with active span', () => { diff --git a/packages/opentelemetry/test/utils/setupEventContextTrace.test.ts b/packages/opentelemetry/test/utils/setupEventContextTrace.test.ts index a73067581b9a..3490e03fedd1 100644 --- a/packages/opentelemetry/test/utils/setupEventContextTrace.test.ts +++ b/packages/opentelemetry/test/utils/setupEventContextTrace.test.ts @@ -28,6 +28,7 @@ describe('setupEventContextTrace', () => { ); hub = new OpenTelemetryHub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); setupEventContextTrace(client); diff --git a/packages/react/test/errorboundary.test.tsx b/packages/react/test/errorboundary.test.tsx index b7acfa12b2af..09ac96a403dd 100644 --- a/packages/react/test/errorboundary.test.tsx +++ b/packages/react/test/errorboundary.test.tsx @@ -1,4 +1,5 @@ -import { Scope, getClient, getCurrentHub } from '@sentry/browser'; +import { Scope, getClient, setCurrentClient } from '@sentry/browser'; +import type { Client } from '@sentry/types'; import { fireEvent, render, screen } from '@testing-library/react'; import * as React from 'react'; import { useState } from 'react'; @@ -442,13 +443,17 @@ describe('ErrorBoundary', () => { it('shows a Sentry Report Dialog with correct options if client has hooks', () => { let callback: any; - const hub = getCurrentHub(); - // @ts-expect-error mock client - hub.bindClient({ + + const clientBefore = getClient(); + + const client = { on: (name: string, cb: any) => { callback = cb; }, - }); + } as Client; + + setCurrentClient(client); + const options = { title: 'custom title' }; render( You have hit an error

} showDialog dialogOptions={options}> @@ -467,7 +472,7 @@ describe('ErrorBoundary', () => { expect(mockShowReportDialog).toHaveBeenCalledTimes(1); expect(mockShowReportDialog).toHaveBeenCalledWith({ ...options, eventId: EVENT_ID }); - hub.bindClient(undefined); + setCurrentClient(clientBefore!); }); it('resets to initial state when reset', async () => { diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index c227d5d1322e..22ba1883b0d5 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -30,7 +30,9 @@ export { getHubFromCarrier, getCurrentHub, Hub, + // eslint-disable-next-line deprecation/deprecation makeMain, + setCurrentClient, Scope, // eslint-disable-next-line deprecation/deprecation startTransaction, diff --git a/packages/replay/test/unit/util/prepareReplayEvent.test.ts b/packages/replay/test/unit/util/prepareReplayEvent.test.ts index 06b464425808..ac4ae503d10e 100644 --- a/packages/replay/test/unit/util/prepareReplayEvent.test.ts +++ b/packages/replay/test/unit/util/prepareReplayEvent.test.ts @@ -1,5 +1,4 @@ -import { getClient, getCurrentScope } from '@sentry/core'; -import { getCurrentHub } from '@sentry/core'; +import { getClient, getCurrentScope, setCurrentClient } from '@sentry/core'; import type { ReplayEvent } from '@sentry/types'; import { REPLAY_EVENT_NAME } from '../../../src/constants'; @@ -8,9 +7,9 @@ import { TestClient, getDefaultClientOptions } from '../../utils/TestClient'; describe('Unit | util | prepareReplayEvent', () => { beforeEach(() => { - const hub = getCurrentHub(); const client = new TestClient(getDefaultClientOptions()); - hub.bindClient(client); + setCurrentClient(client); + client.init(); jest.spyOn(client, 'getSdkMetadata').mockImplementation(() => { return { diff --git a/packages/serverless/src/index.ts b/packages/serverless/src/index.ts index da5718ed2ca9..f5cc51789a79 100644 --- a/packages/serverless/src/index.ts +++ b/packages/serverless/src/index.ts @@ -35,7 +35,9 @@ export { getGlobalScope, getIsolationScope, getHubFromCarrier, + // eslint-disable-next-line deprecation/deprecation makeMain, + setCurrentClient, setContext, setExtra, setExtras, diff --git a/packages/sveltekit/src/server/index.ts b/packages/sveltekit/src/server/index.ts index 0367f4153094..5e4e13960774 100644 --- a/packages/sveltekit/src/server/index.ts +++ b/packages/sveltekit/src/server/index.ts @@ -28,7 +28,9 @@ export { getGlobalScope, getIsolationScope, Hub, + // eslint-disable-next-line deprecation/deprecation makeMain, + setCurrentClient, Scope, // eslint-disable-next-line deprecation/deprecation startTransaction, diff --git a/packages/sveltekit/test/server/handle.test.ts b/packages/sveltekit/test/server/handle.test.ts index 9f974a6bbdd1..6465cbfe5da5 100644 --- a/packages/sveltekit/test/server/handle.test.ts +++ b/packages/sveltekit/test/server/handle.test.ts @@ -92,6 +92,7 @@ beforeEach(() => { const options = getDefaultNodeClientOptions({ tracesSampleRate: 1.0 }); client = new NodeClient(options); hub = new Hub(client); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); mockCaptureException.mockClear(); diff --git a/packages/tracing-internal/test/browser/backgroundtab.test.ts b/packages/tracing-internal/test/browser/backgroundtab.test.ts index 215a9c5d6583..66310b122cbc 100644 --- a/packages/tracing-internal/test/browser/backgroundtab.test.ts +++ b/packages/tracing-internal/test/browser/backgroundtab.test.ts @@ -16,6 +16,7 @@ conditionalTest({ min: 10 })('registerBackgroundTabDetection', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); hub = new Hub(new TestClient(options)); + // eslint-disable-next-line deprecation/deprecation makeMain(hub); // If we do not add extension methods, invoking hub.startTransaction returns undefined diff --git a/packages/tracing-internal/test/browser/browsertracing.test.ts b/packages/tracing-internal/test/browser/browsertracing.test.ts index 3cbd6eb9f6b4..81efa21d869f 100644 --- a/packages/tracing-internal/test/browser/browsertracing.test.ts +++ b/packages/tracing-internal/test/browser/browsertracing.test.ts @@ -1,5 +1,5 @@ /* eslint-disable deprecation/deprecation */ -import { Hub, TRACING_DEFAULTS, makeMain } from '@sentry/core'; +import { Hub, TRACING_DEFAULTS, makeMain, setCurrentClient } from '@sentry/core'; import * as hubExtensions from '@sentry/core'; import type { BaseTransportOptions, ClientOptions, DsnComponents, HandlerDataHistory } from '@sentry/types'; import { JSDOM } from 'jsdom'; @@ -659,7 +659,9 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { const tracesSampler = jest.fn(); const options = getDefaultBrowserClientOptions({ tracesSampler }); - hub.bindClient(new TestClient(options)); + const client = new TestClient(options); + setCurrentClient(client); + client.init(); // setting up the BrowserTracing integration automatically starts a pageload transaction createBrowserTracing(true); @@ -676,7 +678,9 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { const tracesSampler = jest.fn(); const options = getDefaultBrowserClientOptions({ tracesSampler }); - hub.bindClient(new TestClient(options)); + const client = new TestClient(options); + setCurrentClient(client); + client.init(); // setting up the BrowserTracing integration normally automatically starts a pageload transaction, but that's not // what we're testing here createBrowserTracing(true, { startTransactionOnPageLoad: false }); diff --git a/packages/tracing-internal/test/browser/request.test.ts b/packages/tracing-internal/test/browser/request.test.ts index 3dabe104c8f6..faa2d5b96600 100644 --- a/packages/tracing-internal/test/browser/request.test.ts +++ b/packages/tracing-internal/test/browser/request.test.ts @@ -1,5 +1,6 @@ /* eslint-disable deprecation/deprecation */ import * as sentryCore from '@sentry/core'; +import { Hub, makeMain, spanToJSON } from '@sentry/core'; import type { HandlerDataFetch, HandlerDataXhr, SentryWrappedXMLHttpRequest } from '@sentry/types'; import * as utils from '@sentry/utils'; import { SENTRY_XHR_DATA_KEY } from '@sentry/utils'; @@ -59,7 +60,7 @@ describe('instrumentOutgoingRequests', () => { }); describe('callbacks', () => { - let hub: sentryCore.Hub; + let hub: Hub; let transaction: Transaction; const alwaysCreateSpan = () => true; const alwaysAttachHeaders = () => true; @@ -68,8 +69,8 @@ describe('callbacks', () => { beforeAll(() => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - hub = new sentryCore.Hub(new TestClient(options)); - sentryCore.makeMain(hub); + hub = new Hub(new TestClient(options)); + makeMain(hub); }); beforeEach(() => { @@ -256,7 +257,7 @@ describe('callbacks', () => { expect(finishedSpan).toBeDefined(); expect(finishedSpan).toBeInstanceOf(Span); - expect(sentryCore.spanToJSON(finishedSpan).data).toEqual({ + expect(spanToJSON(finishedSpan).data).toEqual({ 'http.response_content_length': 123, 'http.method': 'GET', 'http.response.status_code': 404, diff --git a/packages/types/src/hub.ts b/packages/types/src/hub.ts index 014738c84e83..0656d55644f8 100644 --- a/packages/types/src/hub.ts +++ b/packages/types/src/hub.ts @@ -28,6 +28,8 @@ export interface Hub { /** * This binds the given client to the current scope. * @param client An SDK client (client) instance. + * + * @deprecated Use `initAndBind()` directly. */ bindClient(client?: Client): void; diff --git a/packages/vercel-edge/src/index.ts b/packages/vercel-edge/src/index.ts index 8fcc124256dc..0e2606ebb33b 100644 --- a/packages/vercel-edge/src/index.ts +++ b/packages/vercel-edge/src/index.ts @@ -49,7 +49,9 @@ export { Hub, // eslint-disable-next-line deprecation/deprecation lastEventId, + // eslint-disable-next-line deprecation/deprecation makeMain, + setCurrentClient, runWithAsyncContext, Scope, // eslint-disable-next-line deprecation/deprecation diff --git a/packages/vue/test/errorHandler.test.ts b/packages/vue/test/errorHandler.test.ts index 05727f561297..3245fa80a356 100644 --- a/packages/vue/test/errorHandler.test.ts +++ b/packages/vue/test/errorHandler.test.ts @@ -1,4 +1,4 @@ -import { getCurrentHub } from '@sentry/browser'; +import { setCurrentClient } from '@sentry/browser'; import { attachErrorHandler } from '../src/errorhandler'; import type { Operation, Options, ViewModel, Vue } from '../src/types'; @@ -333,7 +333,7 @@ const testHarness = ({ const client: any = { captureException: jest.fn(async () => Promise.resolve()), }; - getCurrentHub().bindClient(client); + setCurrentClient(client); const app: Vue = { config: { From 64a7efee72baff8a213f546d0e8ebcaae88c8095 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 16 Jan 2024 08:18:48 +0100 Subject: [PATCH 2/2] bump size limit --- .size-limit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.size-limit.js b/.size-limit.js index b29677fce51a..2ddf44088be9 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -72,7 +72,7 @@ module.exports = [ name: '@sentry/browser (incl. Tracing) - ES6 CDN Bundle (gzipped)', path: 'packages/browser/build/bundles/bundle.tracing.min.js', gzip: true, - limit: '35 KB', + limit: '37 KB', }, { name: '@sentry/browser - ES6 CDN Bundle (gzipped)', @@ -94,7 +94,7 @@ module.exports = [ path: 'packages/browser/build/bundles/bundle.tracing.min.js', gzip: false, brotli: false, - limit: '100 KB', + limit: '105 KB', }, { name: '@sentry/browser - ES6 CDN Bundle (minified & uncompressed)',