From 8b9767ab8535db4b9be0d9cbe1398b3aa7f69b5a Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 22 Nov 2023 11:50:19 +0100 Subject: [PATCH 1/2] feat(core): Add `getClient` method This can be used instead of `getCurrentHub().getClient()`. --- packages/angular/src/errorhandler.ts | 2 +- packages/angular/test/errorhandler.test.ts | 7 ++----- packages/astro/src/index.server.ts | 1 + packages/astro/test/client/sdk.test.ts | 12 +++++------ packages/browser/src/exports.ts | 1 + .../browser/src/integrations/breadcrumbs.ts | 3 ++- packages/browser/src/profiling/utils.ts | 3 ++- packages/browser/src/sdk.ts | 3 ++- .../browser/test/unit/eventbuilder.test.ts | 13 +++++++----- packages/browser/test/unit/index.test.ts | 21 ++++++++++--------- .../unit/integrations/breadcrumbs.test.ts | 5 ++++- .../test/unit/profiling/integration.test.ts | 4 ++-- packages/bun/src/index.ts | 1 + packages/core/src/exports.ts | 12 +++++++++-- packages/core/src/index.ts | 1 + packages/core/src/integration.ts | 3 ++- packages/core/src/utils/hasTracingEnabled.ts | 4 ++-- packages/deno/src/index.ts | 1 + packages/feedback/test/sendFeedback.test.ts | 4 ++-- .../pagesRouterRoutingInstrumentation.ts | 4 ++-- packages/nextjs/src/common/_error.ts | 4 ++-- .../wrapDocumentGetInitialPropsWithSentry.ts | 4 ++-- .../common/wrapGetStaticPropsWithSentry.ts | 4 ++-- packages/node-experimental/src/index.ts | 2 +- .../src/integrations/http.ts | 4 ++-- .../src/integrations/node-fetch.ts | 4 ++-- .../node-experimental/src/sdk/initOtel.ts | 4 ++-- .../src/sdk/spanProcessor.ts | 4 ++-- packages/node/src/anr/index.ts | 4 ++-- packages/node/src/handlers.ts | 3 ++- packages/node/src/index.ts | 1 + .../src/integrations/onuncaughtexception.ts | 4 ++-- .../src/integrations/utils/errorhandling.ts | 4 ++-- packages/node/test/index.test.ts | 16 +++++++------- .../aggregates-disable-single-session.js | 2 +- .../opentelemetry-node/src/spanprocessor.ts | 6 +++--- packages/opentelemetry/src/custom/hub.ts | 5 +++++ packages/opentelemetry/src/index.ts | 2 +- packages/opentelemetry/src/propagator.ts | 4 ++-- packages/opentelemetry/src/trace.ts | 4 ++-- packages/react/src/errorboundary.tsx | 4 ++-- packages/react/src/redux.ts | 4 ++-- packages/react/test/errorboundary.test.tsx | 4 ++-- .../src/coreHandlers/handleAfterSendEvent.ts | 4 ++-- .../coreHandlers/handleNetworkBreadcrumbs.ts | 4 ++-- packages/replay/src/integration.ts | 4 ++-- packages/replay/src/replay.ts | 4 ++-- packages/replay/src/util/addEvent.ts | 4 ++-- .../replay/src/util/addGlobalListeners.ts | 4 ++-- .../coreHandlers/handleAfterSendEvent.test.ts | 20 +++++++++--------- .../test/integration/errorSampleRate.test.ts | 6 +++--- .../replay/test/integration/events.test.ts | 4 ++-- packages/serverless/src/index.ts | 1 + packages/sveltekit/src/server/index.ts | 1 + packages/sveltekit/test/client/sdk.test.ts | 12 +++++------ packages/vercel-edge/src/index.ts | 1 + 56 files changed, 149 insertions(+), 122 deletions(-) diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index 2cc6550c63cb..b776cc4701a3 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -115,7 +115,7 @@ class SentryErrorHandler implements AngularErrorHandler { // Optionally show user dialog to provide details on what happened. if (this._options.showDialog) { - const client = Sentry.getCurrentHub().getClient(); + const client = Sentry.getClient(); if (client && client.on && !this._registeredAfterSendEventHandler) { client.on('afterSendEvent', (event: Event) => { diff --git a/packages/angular/test/errorhandler.test.ts b/packages/angular/test/errorhandler.test.ts index d298fd72cdee..a4e16a4e9c66 100644 --- a/packages/angular/test/errorhandler.test.ts +++ b/packages/angular/test/errorhandler.test.ts @@ -1,6 +1,6 @@ import { HttpErrorResponse } from '@angular/common/http'; import * as SentryBrowser from '@sentry/browser'; -import type { Event } from '@sentry/types'; +import type { Client, Event } from '@sentry/types'; import { createErrorHandler, SentryErrorHandler } from '../src/errorhandler'; @@ -505,10 +505,7 @@ describe('SentryErrorHandler', () => { }), }; - // @ts-expect-error this is a minmal hub, we're missing a few props but that's ok - jest.spyOn(SentryBrowser, 'getCurrentHub').mockImplementationOnce(() => { - return { getClient: () => client }; - }); + jest.spyOn(SentryBrowser, 'getClient').mockImplementationOnce(() => client as unknown as Client); const showReportDialogSpy = jest.spyOn(SentryBrowser, 'showReportDialog'); diff --git a/packages/astro/src/index.server.ts b/packages/astro/src/index.server.ts index 9dce9689a7eb..94f19936dd54 100644 --- a/packages/astro/src/index.server.ts +++ b/packages/astro/src/index.server.ts @@ -21,6 +21,7 @@ export { getActiveTransaction, getHubFromCarrier, getCurrentHub, + getClient, Hub, makeMain, Scope, diff --git a/packages/astro/test/client/sdk.test.ts b/packages/astro/test/client/sdk.test.ts index 74a4dc4562ef..d35c501415c7 100644 --- a/packages/astro/test/client/sdk.test.ts +++ b/packages/astro/test/client/sdk.test.ts @@ -1,6 +1,6 @@ import type { BrowserClient } from '@sentry/browser'; import * as SentryBrowser from '@sentry/browser'; -import { BrowserTracing, getCurrentHub, SDK_VERSION, WINDOW } from '@sentry/browser'; +import { BrowserTracing, getClient, getCurrentHub, SDK_VERSION, WINDOW } from '@sentry/browser'; import { vi } from 'vitest'; import { init } from '../../../astro/src/client/sdk'; @@ -60,7 +60,7 @@ describe('Sentry client SDK', () => { }); const integrationsToInit = browserInit.mock.calls[0][0]?.integrations; - const browserTracing = (getCurrentHub().getClient() as BrowserClient)?.getIntegrationById('BrowserTracing'); + const browserTracing = getClient()?.getIntegrationById('BrowserTracing'); expect(integrationsToInit).toContainEqual(expect.objectContaining({ name: 'BrowserTracing' })); expect(browserTracing).toBeDefined(); @@ -76,7 +76,7 @@ describe('Sentry client SDK', () => { }); const integrationsToInit = browserInit.mock.calls[0][0]?.integrations; - const browserTracing = (getCurrentHub().getClient() as BrowserClient)?.getIntegrationById('BrowserTracing'); + const browserTracing = getClient()?.getIntegrationById('BrowserTracing'); expect(integrationsToInit).not.toContainEqual(expect.objectContaining({ name: 'BrowserTracing' })); expect(browserTracing).toBeUndefined(); @@ -91,7 +91,7 @@ describe('Sentry client SDK', () => { }); const integrationsToInit = browserInit.mock.calls[0][0]?.integrations; - const browserTracing = (getCurrentHub().getClient() as BrowserClient)?.getIntegrationById('BrowserTracing'); + const browserTracing = getClient()?.getIntegrationById('BrowserTracing'); expect(integrationsToInit).not.toContainEqual(expect.objectContaining({ name: 'BrowserTracing' })); expect(browserTracing).toBeUndefined(); @@ -108,9 +108,7 @@ describe('Sentry client SDK', () => { const integrationsToInit = browserInit.mock.calls[0][0]?.integrations; - const browserTracing = (getCurrentHub().getClient() as BrowserClient)?.getIntegrationById( - 'BrowserTracing', - ) as BrowserTracing; + const browserTracing = getClient()?.getIntegrationById('BrowserTracing') as BrowserTracing; const options = browserTracing.options; expect(integrationsToInit).toContainEqual(expect.objectContaining({ name: 'BrowserTracing' })); diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index 3d3aec477731..18b9320eafbd 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -33,6 +33,7 @@ export { flush, getHubFromCarrier, getCurrentHub, + getClient, Hub, lastEventId, makeMain, diff --git a/packages/browser/src/integrations/breadcrumbs.ts b/packages/browser/src/integrations/breadcrumbs.ts index f71361b7d96e..c278240c5786 100644 --- a/packages/browser/src/integrations/breadcrumbs.ts +++ b/packages/browser/src/integrations/breadcrumbs.ts @@ -19,6 +19,7 @@ import { severityLevelFromString, } from '@sentry/utils'; +import { getClient } from '../exports'; import { WINDOW } from '../helpers'; type HandlerData = Record; @@ -103,7 +104,7 @@ export class Breadcrumbs implements Integration { addInstrumentationHandler('history', _historyBreadcrumb); } if (this.options.sentry) { - const client = getCurrentHub().getClient(); + const client = getClient(); client && client.on && client.on('beforeSendEvent', addSentryBreadcrumb); } } diff --git a/packages/browser/src/profiling/utils.ts b/packages/browser/src/profiling/utils.ts index 33f6652b2310..4c8a74adf247 100644 --- a/packages/browser/src/profiling/utils.ts +++ b/packages/browser/src/profiling/utils.ts @@ -5,6 +5,7 @@ import type { DebugImage, Envelope, Event, StackFrame, StackParser, Transaction import type { Profile, ThreadCpuProfile } from '@sentry/types/src/profiling'; import { browserPerformanceTimeOrigin, forEachEnvelopeItem, GLOBAL_OBJ, logger, uuid4 } from '@sentry/utils'; +import { getClient } from '../exports'; import { WINDOW } from '../helpers'; import type { JSSelfProfile, JSSelfProfiler, JSSelfProfilerConstructor, JSSelfProfileStack } from './jsSelfProfiling'; @@ -532,7 +533,7 @@ export function shouldProfileTransaction(transaction: Transaction): boolean { return false; } - const client = getCurrentHub().getClient(); + const client = getClient(); const options = client && client.getOptions(); if (!options) { __DEBUG_BUILD__ && logger.log('[Profiling] Profiling disabled, no options found.'); diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index de352d9db154..e7689f3521b1 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -1,5 +1,6 @@ import type { Hub } from '@sentry/core'; import { + getClient, getCurrentHub, getIntegrationsToSetup, getReportDialogEndpoint, @@ -252,7 +253,7 @@ function startSessionTracking(): void { * Captures user feedback and sends it to Sentry. */ export function captureUserFeedback(feedback: UserFeedback): void { - const client = getCurrentHub().getClient(); + const client = getClient(); if (client) { client.captureUserFeedback(feedback); } diff --git a/packages/browser/test/unit/eventbuilder.test.ts b/packages/browser/test/unit/eventbuilder.test.ts index d7a2ab712959..0a5a7911ea08 100644 --- a/packages/browser/test/unit/eventbuilder.test.ts +++ b/packages/browser/test/unit/eventbuilder.test.ts @@ -1,5 +1,3 @@ -import type { Client } from '@sentry/types'; - import { defaultStackParser } from '../../src'; import { eventFromPlainObject } from '../../src/eventbuilder'; @@ -7,9 +5,14 @@ jest.mock('@sentry/core', () => { const original = jest.requireActual('@sentry/core'); return { ...original, - getCurrentHub(): { - getClient(): Client; - } { + getClient() { + return { + getOptions(): any { + return { normalizeDepth: 6 }; + }, + }; + }, + getCurrentHub() { return { getClient(): any { return { diff --git a/packages/browser/test/unit/index.test.ts b/packages/browser/test/unit/index.test.ts index 0b0df3c4300f..fca76fb33b79 100644 --- a/packages/browser/test/unit/index.test.ts +++ b/packages/browser/test/unit/index.test.ts @@ -11,6 +11,7 @@ import { captureMessage, configureScope, flush, + getClient, getCurrentHub, init, Integrations, @@ -271,11 +272,11 @@ describe('SentryBrowser initialization', () => { it('should set SDK data when Sentry.init() is called', () => { init({ dsn }); - const sdkData = (getCurrentHub().getClient() as any).getOptions()._metadata.sdk; + const sdkData = getClient()?.getOptions()._metadata?.sdk || {}; expect(sdkData?.name).toBe('sentry.javascript.browser'); - expect(sdkData?.packages[0].name).toBe('npm:@sentry/browser'); - expect(sdkData?.packages[0].version).toBe(SDK_VERSION); + expect(sdkData?.packages?.[0].name).toBe('npm:@sentry/browser'); + expect(sdkData?.packages?.[0].version).toBe(SDK_VERSION); expect(sdkData?.version).toBe(SDK_VERSION); }); @@ -283,9 +284,9 @@ describe('SentryBrowser initialization', () => { global.SENTRY_SDK_SOURCE = 'loader'; init({ dsn }); - const sdkData = (getCurrentHub().getClient() as any).getOptions()._metadata.sdk; + const sdkData = getClient()?.getOptions()._metadata?.sdk || {}; - expect(sdkData?.packages[0].name).toBe('loader:@sentry/browser'); + expect(sdkData.packages?.[0].name).toBe('loader:@sentry/browser'); delete global.SENTRY_SDK_SOURCE; }); @@ -293,9 +294,9 @@ describe('SentryBrowser initialization', () => { const spy = jest.spyOn(utils, 'getSDKSource').mockReturnValue('cdn'); init({ dsn }); - const sdkData = (getCurrentHub().getClient() as any).getOptions()._metadata.sdk; + const sdkData = getClient()?.getOptions()._metadata?.sdk || {}; - expect(sdkData?.packages[0].name).toBe('cdn:@sentry/browser'); + expect(sdkData.packages?.[0].name).toBe('cdn:@sentry/browser'); expect(utils.getSDKSource).toBeCalledTimes(1); spy.mockRestore(); }); @@ -332,11 +333,11 @@ describe('SentryBrowser initialization', () => { }, }); - const sdkData = (getCurrentHub().getClient() as any).getOptions()._metadata?.sdk; + const sdkData = getClient()?.getOptions()._metadata?.sdk || {}; expect(sdkData.name).toBe('sentry.javascript.angular'); - expect(sdkData.packages[0].name).toBe('npm:@sentry/angular'); - expect(sdkData.packages[0].version).toBe(SDK_VERSION); + expect(sdkData.packages?.[0].name).toBe('npm:@sentry/angular'); + expect(sdkData.packages?.[0].version).toBe(SDK_VERSION); expect(sdkData.version).toBe(SDK_VERSION); }); }); diff --git a/packages/browser/test/unit/integrations/breadcrumbs.test.ts b/packages/browser/test/unit/integrations/breadcrumbs.test.ts index f2deb2302c3c..04025e472ecc 100644 --- a/packages/browser/test/unit/integrations/breadcrumbs.test.ts +++ b/packages/browser/test/unit/integrations/breadcrumbs.test.ts @@ -1,15 +1,18 @@ import { getCurrentHub } from '@sentry/core'; +import type { Client } from '@sentry/types'; import { Breadcrumbs, BrowserClient, flush, Hub } 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, }; }); @@ -18,7 +21,7 @@ describe('Breadcrumbs', () => { const addBreadcrumb = jest.fn(); hub.addBreadcrumb = addBreadcrumb; - const client = new BrowserClient({ + client = new BrowserClient({ ...getDefaultBrowserClientOptions(), dsn: 'https://username@domain/123', integrations: [new Breadcrumbs()], diff --git a/packages/browser/test/unit/profiling/integration.test.ts b/packages/browser/test/unit/profiling/integration.test.ts index 0060a4e6b000..515398638048 100644 --- a/packages/browser/test/unit/profiling/integration.test.ts +++ b/packages/browser/test/unit/profiling/integration.test.ts @@ -48,12 +48,12 @@ describe('BrowserProfilingIntegration', () => { integrations: [new Sentry.BrowserTracing(), new BrowserProfilingIntegration()], }); - const client = Sentry.getCurrentHub().getClient() as BrowserClient; + const client = Sentry.getClient(); const currentTransaction = Sentry.getCurrentHub().getScope().getTransaction(); expect(currentTransaction?.op).toBe('pageload'); currentTransaction?.finish(); - await client.flush(1000); + await client?.flush(1000); expect(send).toHaveBeenCalledTimes(1); diff --git a/packages/bun/src/index.ts b/packages/bun/src/index.ts index 9750a2ba7815..baae8ff4fa32 100644 --- a/packages/bun/src/index.ts +++ b/packages/bun/src/index.ts @@ -39,6 +39,7 @@ export { getActiveTransaction, getHubFromCarrier, getCurrentHub, + getClient, Hub, lastEventId, makeMain, diff --git a/packages/core/src/exports.ts b/packages/core/src/exports.ts index 2be61f2fa940..6d1d52e60863 100644 --- a/packages/core/src/exports.ts +++ b/packages/core/src/exports.ts @@ -2,6 +2,7 @@ import type { Breadcrumb, CaptureContext, CheckIn, + Client, CustomSamplingContext, Event, EventHint, @@ -266,7 +267,7 @@ export function withMonitor( * doesn't (or if there's no client defined). */ export async function flush(timeout?: number): Promise { - const client = getCurrentHub().getClient(); + const client = getClient(); if (client) { return client.flush(timeout); } @@ -283,7 +284,7 @@ export async function flush(timeout?: number): Promise { * doesn't (or if there's no client defined). */ export async function close(timeout?: number): Promise { - const client = getCurrentHub().getClient(); + const client = getClient(); if (client) { return client.close(timeout); } @@ -299,3 +300,10 @@ export async function close(timeout?: number): Promise { export function lastEventId(): string | undefined { return getCurrentHub().lastEventId(); } + +/** + * Get the currently active client. + */ +export function getClient(): C | undefined { + return getCurrentHub().getClient(); +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d2b856a7cb37..eda5cfe867d6 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -24,6 +24,7 @@ export { setTags, setUser, withScope, + getClient, } from './exports'; export { getCurrentHub, diff --git a/packages/core/src/integration.ts b/packages/core/src/integration.ts index 25e8d41225bd..8b05139af74b 100644 --- a/packages/core/src/integration.ts +++ b/packages/core/src/integration.ts @@ -2,6 +2,7 @@ import type { Client, Event, EventHint, Integration, Options } from '@sentry/typ import { arrayify, logger } from '@sentry/utils'; import { addGlobalEventProcessor } from './eventProcessors'; +import { getClient } from './exports'; import { getCurrentHub } from './hub'; declare module '@sentry/types' { @@ -132,7 +133,7 @@ export function setupIntegration(client: Client, integration: Integration, integ /** Add an integration to the current hub's client. */ export function addIntegration(integration: Integration): void { - const client = getCurrentHub().getClient(); + const client = getClient(); if (!client || !client.addIntegration) { __DEBUG_BUILD__ && logger.warn(`Cannot add integration "${integration.name}" because no SDK Client is available.`); diff --git a/packages/core/src/utils/hasTracingEnabled.ts b/packages/core/src/utils/hasTracingEnabled.ts index 65dad5883ba2..94c5ab13e5ae 100644 --- a/packages/core/src/utils/hasTracingEnabled.ts +++ b/packages/core/src/utils/hasTracingEnabled.ts @@ -1,6 +1,6 @@ import type { Options } from '@sentry/types'; -import { getCurrentHub } from '../hub'; +import { getClient } from '../exports'; // Treeshakable guard to remove all code related to tracing declare const __SENTRY_TRACING__: boolean | undefined; @@ -17,7 +17,7 @@ export function hasTracingEnabled( return false; } - const client = getCurrentHub().getClient(); + const client = getClient(); const options = maybeOptions || (client && client.getOptions()); return !!options && (options.enableTracing || 'tracesSampleRate' in options || 'tracesSampler' in options); } diff --git a/packages/deno/src/index.ts b/packages/deno/src/index.ts index 3301e50db6c2..093ed25380de 100644 --- a/packages/deno/src/index.ts +++ b/packages/deno/src/index.ts @@ -38,6 +38,7 @@ export { getActiveTransaction, getHubFromCarrier, getCurrentHub, + getClient, Hub, lastEventId, makeMain, diff --git a/packages/feedback/test/sendFeedback.test.ts b/packages/feedback/test/sendFeedback.test.ts index 960411d8949e..e7c836527089 100644 --- a/packages/feedback/test/sendFeedback.test.ts +++ b/packages/feedback/test/sendFeedback.test.ts @@ -1,4 +1,4 @@ -import { getCurrentHub } from '@sentry/core'; +import { getClient } from '@sentry/core'; import { sendFeedback } from '../src/sendFeedback'; import { mockSdk } from './utils/mockSdk'; @@ -6,7 +6,7 @@ import { mockSdk } from './utils/mockSdk'; describe('sendFeedback', () => { it('sends feedback', async () => { mockSdk(); - const mockTransport = jest.spyOn(getCurrentHub().getClient()!.getTransport()!, 'send'); + const mockTransport = jest.spyOn(getClient()!.getTransport()!, 'send'); await sendFeedback({ name: 'doe', diff --git a/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts b/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts index a633e1cec6dc..c1f8bdc5ccfe 100644 --- a/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts +++ b/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts @@ -1,4 +1,4 @@ -import { getCurrentHub } from '@sentry/core'; +import { getClient, getCurrentHub } from '@sentry/core'; import { WINDOW } from '@sentry/react'; import type { Primitive, Transaction, TransactionContext, TransactionSource } from '@sentry/types'; import { @@ -101,7 +101,7 @@ let activeTransaction: Transaction | undefined = undefined; // This is either a route or a pathname. let prevLocationName: string | undefined = undefined; -const client = getCurrentHub().getClient(); +const client = getClient(); /** * Instruments the Next.js pages router. Only supported for diff --git a/packages/nextjs/src/common/_error.ts b/packages/nextjs/src/common/_error.ts index c69c725c3137..1ddd5ea63e01 100644 --- a/packages/nextjs/src/common/_error.ts +++ b/packages/nextjs/src/common/_error.ts @@ -1,4 +1,4 @@ -import { captureException, getCurrentHub, withScope } from '@sentry/core'; +import { captureException, getClient, withScope } from '@sentry/core'; import type { NextPageContext } from 'next'; type ContextOrProps = { @@ -11,7 +11,7 @@ type ContextOrProps = { /** Platform-agnostic version of `flush` */ function flush(timeout?: number): PromiseLike { - const client = getCurrentHub().getClient(); + const client = getClient(); return client ? client.flush(timeout) : Promise.resolve(false); } diff --git a/packages/nextjs/src/common/wrapDocumentGetInitialPropsWithSentry.ts b/packages/nextjs/src/common/wrapDocumentGetInitialPropsWithSentry.ts index 65afef8cc71f..df801a8bc027 100644 --- a/packages/nextjs/src/common/wrapDocumentGetInitialPropsWithSentry.ts +++ b/packages/nextjs/src/common/wrapDocumentGetInitialPropsWithSentry.ts @@ -1,4 +1,4 @@ -import { addTracingExtensions, getCurrentHub } from '@sentry/core'; +import { addTracingExtensions, getClient } from '@sentry/core'; import type Document from 'next/document'; import { isBuild } from './utils/isBuild'; @@ -29,7 +29,7 @@ export function wrapDocumentGetInitialPropsWithSentry( const { req, res } = context; const errorWrappedGetInitialProps = withErrorInstrumentation(wrappingTarget); - const options = getCurrentHub().getClient()?.getOptions(); + const options = getClient()?.getOptions(); // Generally we can assume that `req` and `res` are always defined on the server: // https://nextjs.org/docs/api-reference/data-fetching/get-initial-props#context-object diff --git a/packages/nextjs/src/common/wrapGetStaticPropsWithSentry.ts b/packages/nextjs/src/common/wrapGetStaticPropsWithSentry.ts index 8e141e173ae6..5d2446d50769 100644 --- a/packages/nextjs/src/common/wrapGetStaticPropsWithSentry.ts +++ b/packages/nextjs/src/common/wrapGetStaticPropsWithSentry.ts @@ -1,4 +1,4 @@ -import { addTracingExtensions, getCurrentHub } from '@sentry/core'; +import { addTracingExtensions, getClient } from '@sentry/core'; import type { GetStaticProps } from 'next'; import { isBuild } from './utils/isBuild'; @@ -26,7 +26,7 @@ export function wrapGetStaticPropsWithSentry( addTracingExtensions(); const errorWrappedGetStaticProps = withErrorInstrumentation(wrappingTarget); - const options = getCurrentHub().getClient()?.getOptions(); + const options = getClient()?.getOptions(); if (options?.instrumenter === 'sentry') { return callDataFetcherTraced(errorWrappedGetStaticProps, args, { diff --git a/packages/node-experimental/src/index.ts b/packages/node-experimental/src/index.ts index 740c52b92bb8..e14572b14b6a 100644 --- a/packages/node-experimental/src/index.ts +++ b/packages/node-experimental/src/index.ts @@ -13,7 +13,7 @@ export { getAutoPerformanceIntegrations } from './integrations/getAutoPerformanc export * as Handlers from './sdk/handlers'; export type { Span } from './types'; -export { startSpan, startInactiveSpan, getCurrentHub, getActiveSpan } from '@sentry/opentelemetry'; +export { startSpan, startInactiveSpan, getCurrentHub, getClient, getActiveSpan } from '@sentry/opentelemetry'; export { makeNodeTransport, diff --git a/packages/node-experimental/src/integrations/http.ts b/packages/node-experimental/src/integrations/http.ts index 69712e503761..f21aa9507395 100644 --- a/packages/node-experimental/src/integrations/http.ts +++ b/packages/node-experimental/src/integrations/http.ts @@ -3,7 +3,7 @@ import { SpanKind } from '@opentelemetry/api'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'; import { hasTracingEnabled, isSentryRequestUrl } from '@sentry/core'; -import { _INTERNAL, getCurrentHub, getSpanKind, setSpanMetadata } from '@sentry/opentelemetry'; +import { _INTERNAL, getClient, getSpanKind, setSpanMetadata, getCurrentHub } from '@sentry/opentelemetry'; import type { EventProcessor, Hub, Integration } from '@sentry/types'; import { stringMatchesSomePattern } from '@sentry/utils'; import type { ClientRequest, IncomingMessage, ServerResponse } from 'http'; @@ -84,7 +84,7 @@ export class Http implements Integration { return; } - const client = getCurrentHub().getClient(); + const client = getClient(); const clientOptions = client?.getOptions(); // This is used in the sampler function diff --git a/packages/node-experimental/src/integrations/node-fetch.ts b/packages/node-experimental/src/integrations/node-fetch.ts index bc1f776d950a..53d15dbce6c3 100644 --- a/packages/node-experimental/src/integrations/node-fetch.ts +++ b/packages/node-experimental/src/integrations/node-fetch.ts @@ -2,7 +2,7 @@ import type { Span } from '@opentelemetry/api'; import { SpanKind } from '@opentelemetry/api'; import type { Instrumentation } from '@opentelemetry/instrumentation'; import { hasTracingEnabled } from '@sentry/core'; -import { _INTERNAL, getCurrentHub, getSpanKind } from '@sentry/opentelemetry'; +import { _INTERNAL, getCurrentHub, getSpanKind, getClient } from '@sentry/opentelemetry'; import type { Integration } from '@sentry/types'; import type { NodeExperimentalClient } from '../types'; @@ -87,7 +87,7 @@ export class NodeFetch extends NodePerformanceIntegration impl public setupOnce(): void { super.setupOnce(); - const client = getCurrentHub().getClient(); + const client = getClient(); const clientOptions = client?.getOptions(); // This is used in the sampler function diff --git a/packages/node-experimental/src/sdk/initOtel.ts b/packages/node-experimental/src/sdk/initOtel.ts index 271135728186..7b33df8431f1 100644 --- a/packages/node-experimental/src/sdk/initOtel.ts +++ b/packages/node-experimental/src/sdk/initOtel.ts @@ -5,7 +5,7 @@ import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; import { SDK_VERSION } from '@sentry/core'; import { - getCurrentHub, + getClient, SentryPropagator, SentrySampler, setupEventContextTrace, @@ -20,7 +20,7 @@ import { NodeExperimentalSentrySpanProcessor } from './spanProcessor'; * Initialize OpenTelemetry for Node. */ export function initOtel(): void { - const client = getCurrentHub().getClient(); + const client = getClient(); if (!client) { __DEBUG_BUILD__ && diff --git a/packages/node-experimental/src/sdk/spanProcessor.ts b/packages/node-experimental/src/sdk/spanProcessor.ts index 4d120b1e80e6..5b6870cbc9fd 100644 --- a/packages/node-experimental/src/sdk/spanProcessor.ts +++ b/packages/node-experimental/src/sdk/spanProcessor.ts @@ -1,7 +1,7 @@ import { SpanKind } from '@opentelemetry/api'; import type { Span } from '@opentelemetry/sdk-trace-base'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; -import { getCurrentHub, SentrySpanProcessor } from '@sentry/opentelemetry'; +import { getClient, SentrySpanProcessor } from '@sentry/opentelemetry'; import { Http } from '../integrations/http'; import { NodeFetch } from '../integrations/node-fetch'; @@ -13,7 +13,7 @@ import type { NodeExperimentalClient } from '../types'; export class NodeExperimentalSentrySpanProcessor extends SentrySpanProcessor { /** @inheritDoc */ protected _shouldSendSpanToSentry(span: Span): boolean { - const client = getCurrentHub().getClient(); + const client = getClient(); const httpIntegration = client ? client.getIntegration(Http) : undefined; const fetchIntegration = client ? client.getIntegration(NodeFetch) : undefined; diff --git a/packages/node/src/anr/index.ts b/packages/node/src/anr/index.ts index 549b962d4b70..e2b5b62b1c3c 100644 --- a/packages/node/src/anr/index.ts +++ b/packages/node/src/anr/index.ts @@ -1,4 +1,4 @@ -import { makeSession, updateSession } from '@sentry/core'; +import { getClient, makeSession, updateSession } from '@sentry/core'; import type { Event, Session, StackFrame } from '@sentry/types'; import { logger, watchdogTimer } from '@sentry/utils'; import { spawn } from 'child_process'; @@ -173,7 +173,7 @@ function handleChildProcess(options: Options): void { if (session) { log('Sending abnormal session'); updateSession(session, { status: 'abnormal', abnormal_mechanism: 'anr_foreground' }); - getCurrentHub().getClient()?.sendSession(session); + getClient()?.sendSession(session); try { // Notify the main process that the session has ended so the session can be cleared from the scope diff --git a/packages/node/src/handlers.ts b/packages/node/src/handlers.ts index df438276231e..d51a2c16d288 100644 --- a/packages/node/src/handlers.ts +++ b/packages/node/src/handlers.ts @@ -3,6 +3,7 @@ import { captureException, continueTrace, flush, + getClient, getCurrentHub, hasTracingEnabled, runWithAsyncContext, @@ -278,7 +279,7 @@ export function errorHandler(options?: { _scope.setSpan(transaction); } - const client = getCurrentHub().getClient(); + const client = getClient(); if (client && isAutoSessionTrackingEnabled(client)) { // Check if the `SessionFlusher` is instantiated on the client to go into this branch that marks the // `requestSession.status` as `Crashed`, and this check is necessary because the `SessionFlusher` is only diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 3c4a28489aa8..b7856c0046d1 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -39,6 +39,7 @@ export { getActiveTransaction, getHubFromCarrier, getCurrentHub, + getClient, Hub, lastEventId, makeMain, diff --git a/packages/node/src/integrations/onuncaughtexception.ts b/packages/node/src/integrations/onuncaughtexception.ts index b4f99b419fd4..b1699f464960 100644 --- a/packages/node/src/integrations/onuncaughtexception.ts +++ b/packages/node/src/integrations/onuncaughtexception.ts @@ -1,5 +1,5 @@ import type { Scope } from '@sentry/core'; -import { getCurrentHub } from '@sentry/core'; +import { getClient, getCurrentHub } from '@sentry/core'; import type { Integration } from '@sentry/types'; import { logger } from '@sentry/utils'; @@ -86,7 +86,7 @@ export class OnUncaughtException implements Integration { return (error: Error): void => { let onFatalError: OnFatalErrorHandler = logAndExitProcess; - const client = getCurrentHub().getClient(); + const client = getClient(); if (this._options.onFatalError) { onFatalError = this._options.onFatalError; diff --git a/packages/node/src/integrations/utils/errorhandling.ts b/packages/node/src/integrations/utils/errorhandling.ts index cf52929fa642..e3f03f064421 100644 --- a/packages/node/src/integrations/utils/errorhandling.ts +++ b/packages/node/src/integrations/utils/errorhandling.ts @@ -1,4 +1,4 @@ -import { getCurrentHub } from '@sentry/core'; +import { getClient } from '@sentry/core'; import { logger } from '@sentry/utils'; import type { NodeClient } from '../../client'; @@ -12,7 +12,7 @@ export function logAndExitProcess(error: Error): void { // eslint-disable-next-line no-console console.error(error); - const client = getCurrentHub().getClient(); + const client = getClient(); if (client === undefined) { __DEBUG_BUILD__ && logger.warn('No NodeClient was defined, we are exiting the process now.'); diff --git a/packages/node/test/index.test.ts b/packages/node/test/index.test.ts index 24f2b95e398b..0d55b4be6da3 100644 --- a/packages/node/test/index.test.ts +++ b/packages/node/test/index.test.ts @@ -8,6 +8,7 @@ import { captureException, captureMessage, configureScope, + getClient, getCurrentHub, init, NodeClient, @@ -296,6 +297,7 @@ describe('SentryNode', () => { const hub = getCurrentHub(); hub.bindClient(client); expect(getCurrentHub().getClient()).toBe(client); + expect(getClient()).toBe(client); hub.captureEvent({ message: 'test domain' }); }); }); @@ -366,12 +368,11 @@ describe('SentryNode initialization', () => { it('should set SDK data when `Sentry.init()` is called', () => { init({ dsn }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const sdkData = (getCurrentHub().getClient() as any).getOptions()._metadata.sdk; + const sdkData = getClient()?.getOptions()._metadata?.sdk || {}; expect(sdkData.name).toEqual('sentry.javascript.node'); - expect(sdkData.packages[0].name).toEqual('npm:@sentry/node'); - expect(sdkData.packages[0].version).toEqual(SDK_VERSION); + expect(sdkData.packages?.[0].name).toEqual('npm:@sentry/node'); + expect(sdkData.packages?.[0].version).toEqual(SDK_VERSION); expect(sdkData.version).toEqual(SDK_VERSION); }); @@ -408,12 +409,11 @@ describe('SentryNode initialization', () => { }, }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const sdkData = (getCurrentHub().getClient() as any).getOptions()._metadata.sdk; + const sdkData = getClient()?.getOptions()._metadata?.sdk || {}; expect(sdkData.name).toEqual('sentry.javascript.serverless'); - expect(sdkData.packages[0].name).toEqual('npm:@sentry/serverless'); - expect(sdkData.packages[0].version).toEqual(SDK_VERSION); + expect(sdkData.packages?.[0].name).toEqual('npm:@sentry/serverless'); + expect(sdkData.packages?.[0].version).toEqual(SDK_VERSION); expect(sdkData.version).toEqual(SDK_VERSION); }); }); diff --git a/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js b/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js index a9a16809ad41..8fe93e9760fd 100644 --- a/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js +++ b/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js @@ -65,7 +65,7 @@ Sentry.init({ app.use(Sentry.Handlers.requestHandler()); // Hack that resets the 60s default flush interval, and replaces it with just a one second interval -const flusher = Sentry.getCurrentHub().getClient()._sessionFlusher; +const flusher = Sentry.getClient()._sessionFlusher; clearInterval(flusher._intervalId); flusher._intervalId = setInterval(() => flusher.flush(), 1000); diff --git a/packages/opentelemetry-node/src/spanprocessor.ts b/packages/opentelemetry-node/src/spanprocessor.ts index 671cdbb7894a..98ab46c405cb 100644 --- a/packages/opentelemetry-node/src/spanprocessor.ts +++ b/packages/opentelemetry-node/src/spanprocessor.ts @@ -2,7 +2,7 @@ import type { Context } from '@opentelemetry/api'; import { context, SpanKind, trace } from '@opentelemetry/api'; import { suppressTracing } from '@opentelemetry/core'; import type { Span as OtelSpan, SpanProcessor as OtelSpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { addGlobalEventProcessor, addTracingExtensions, getCurrentHub, Transaction } from '@sentry/core'; +import { addGlobalEventProcessor, addTracingExtensions, getClient, getCurrentHub, Transaction } from '@sentry/core'; import type { DynamicSamplingContext, Span as SentrySpan, TraceparentData, TransactionContext } from '@sentry/types'; import { logger } from '@sentry/utils'; @@ -100,7 +100,7 @@ export class SentrySpanProcessor implements OtelSpanProcessor { return; } - const client = getCurrentHub().getClient(); + const client = getClient(); const mutableOptions = { drop: false }; client && client.emit && client?.emit('otelSpanEnd', otelSpan, mutableOptions); @@ -141,7 +141,7 @@ export class SentrySpanProcessor implements OtelSpanProcessor { * @inheritDoc */ public async forceFlush(): Promise { - const client = getCurrentHub().getClient(); + const client = getClient(); if (client) { return client.flush().then(); } diff --git a/packages/opentelemetry/src/custom/hub.ts b/packages/opentelemetry/src/custom/hub.ts index 46dccd3c86e4..339cba87ce4d 100644 --- a/packages/opentelemetry/src/custom/hub.ts +++ b/packages/opentelemetry/src/custom/hub.ts @@ -28,6 +28,11 @@ export class OpenTelemetryHub extends Hub { } } +/** Custom getClient method that uses the custom hub. */ +export function getClient(): C | undefined { + return getCurrentHub().getClient(); +} + /** * ******************************************************************************* * Everything below here is a copy of the stuff from core's hub.ts, diff --git a/packages/opentelemetry/src/index.ts b/packages/opentelemetry/src/index.ts index eb516e03dea1..3ac617aada9d 100644 --- a/packages/opentelemetry/src/index.ts +++ b/packages/opentelemetry/src/index.ts @@ -24,7 +24,7 @@ export { isSentryRequestSpan } from './utils/isSentryRequest'; export { getActiveSpan, getRootSpan } from './utils/getActiveSpan'; export { startSpan, startInactiveSpan } from './trace'; -export { getCurrentHub, setupGlobalHub } from './custom/hub'; +export { getCurrentHub, setupGlobalHub, getClient } from './custom/hub'; export { addTracingExtensions } from './custom/hubextensions'; export { setupEventContextTrace } from './setupEventContextTrace'; diff --git a/packages/opentelemetry/src/propagator.ts b/packages/opentelemetry/src/propagator.ts index db7a78d4f8f2..d2cf6dbe5556 100644 --- a/packages/opentelemetry/src/propagator.ts +++ b/packages/opentelemetry/src/propagator.ts @@ -6,7 +6,7 @@ import type { DynamicSamplingContext, PropagationContext } from '@sentry/types'; import { generateSentryTraceHeader, SENTRY_BAGGAGE_KEY_PREFIX, tracingContextFromHeaders } from '@sentry/utils'; import { SENTRY_BAGGAGE_HEADER, SENTRY_TRACE_HEADER } from './constants'; -import { getCurrentHub } from './custom/hub'; +import { getClient } from './custom/hub'; import { getPropagationContextFromContext, setPropagationContextOnContext } from './utils/contextData'; import { getSpanScope } from './utils/spanData'; @@ -90,7 +90,7 @@ function getDsc( } // Else, we try to generate a new one - const client = getCurrentHub().getClient(); + const client = getClient(); const activeSpan = trace.getSpan(context); const scope = activeSpan ? getSpanScope(activeSpan) : undefined; diff --git a/packages/opentelemetry/src/trace.ts b/packages/opentelemetry/src/trace.ts index e7a8fcaef8ea..3bd635a953df 100644 --- a/packages/opentelemetry/src/trace.ts +++ b/packages/opentelemetry/src/trace.ts @@ -4,7 +4,7 @@ import { SDK_VERSION } from '@sentry/core'; import type { Client } from '@sentry/types'; import { isThenable } from '@sentry/utils'; -import { getCurrentHub } from './custom/hub'; +import { getClient } from './custom/hub'; import { InternalSentrySemanticAttributes } from './semanticAttributes'; import type { OpenTelemetryClient, OpenTelemetrySpanContext } from './types'; import { setSpanMetadata } from './utils/spanData'; @@ -85,7 +85,7 @@ export function startInactiveSpan(spanContext: OpenTelemetrySpanContext): Span { } function getTracer(): Tracer { - const client = getCurrentHub().getClient(); + const client = getClient(); return (client && client.tracer) || trace.getTracer('@sentry/opentelemetry', SDK_VERSION); } diff --git a/packages/react/src/errorboundary.tsx b/packages/react/src/errorboundary.tsx index 075b5f8b00bf..61dd976050f6 100644 --- a/packages/react/src/errorboundary.tsx +++ b/packages/react/src/errorboundary.tsx @@ -1,5 +1,5 @@ import type { ReportDialogOptions, Scope } from '@sentry/browser'; -import { captureException, getCurrentHub, showReportDialog, withScope } from '@sentry/browser'; +import { captureException, getClient, showReportDialog, withScope } from '@sentry/browser'; import { isError, logger } from '@sentry/utils'; import hoistNonReactStatics from 'hoist-non-react-statics'; import * as React from 'react'; @@ -104,7 +104,7 @@ class ErrorBoundary extends React.Component { diff --git a/packages/react/src/redux.ts b/packages/react/src/redux.ts index cb90424ba4ad..360e6d7b1382 100644 --- a/packages/react/src/redux.ts +++ b/packages/react/src/redux.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { addGlobalEventProcessor, configureScope, getCurrentHub } from '@sentry/browser'; +import { addGlobalEventProcessor, configureScope, getClient } from '@sentry/browser'; import type { Scope } from '@sentry/types'; import { addNonEnumerableProperty } from '@sentry/utils'; @@ -130,7 +130,7 @@ function createReduxEnhancer(enhancerOptions?: Partial): /* Set latest state to scope */ const transformedState = options.stateTransformer(newState); if (typeof transformedState !== 'undefined' && transformedState !== null) { - const client = getCurrentHub().getClient(); + const client = getClient(); const options = client && client.getOptions(); const normalizationDepth = (options && options.normalizeDepth) || 3; // default state normalization depth to 3 diff --git a/packages/react/test/errorboundary.test.tsx b/packages/react/test/errorboundary.test.tsx index 52f71552f703..6d77802948eb 100644 --- a/packages/react/test/errorboundary.test.tsx +++ b/packages/react/test/errorboundary.test.tsx @@ -1,4 +1,4 @@ -import { getCurrentHub, Scope } from '@sentry/browser'; +import { getClient, getCurrentHub, Scope } from '@sentry/browser'; import { fireEvent, render, screen } from '@testing-library/react'; import * as React from 'react'; import { useState } from 'react'; @@ -422,7 +422,7 @@ describe('ErrorBoundary', () => { }); it('shows a Sentry Report Dialog with correct options if client does not have hooks', () => { - expect(getCurrentHub().getClient()).toBeUndefined(); + expect(getClient()).toBeUndefined(); const options = { title: 'custom title' }; render( diff --git a/packages/replay/src/coreHandlers/handleAfterSendEvent.ts b/packages/replay/src/coreHandlers/handleAfterSendEvent.ts index 00e3b72d590d..5cc2adf77a59 100644 --- a/packages/replay/src/coreHandlers/handleAfterSendEvent.ts +++ b/packages/replay/src/coreHandlers/handleAfterSendEvent.ts @@ -1,4 +1,4 @@ -import { getCurrentHub } from '@sentry/core'; +import { getClient } from '@sentry/core'; import type { ErrorEvent, Event, TransactionEvent, Transport, TransportMakeRequestResponse } from '@sentry/types'; import type { ReplayContainer } from '../types'; @@ -79,7 +79,7 @@ function handleErrorEvent(replay: ReplayContainer, event: ErrorEvent): void { } function isBaseTransportSend(): boolean { - const client = getCurrentHub().getClient(); + const client = getClient(); if (!client) { return false; } diff --git a/packages/replay/src/coreHandlers/handleNetworkBreadcrumbs.ts b/packages/replay/src/coreHandlers/handleNetworkBreadcrumbs.ts index 20fa00a633eb..a8c14e46fad5 100644 --- a/packages/replay/src/coreHandlers/handleNetworkBreadcrumbs.ts +++ b/packages/replay/src/coreHandlers/handleNetworkBreadcrumbs.ts @@ -1,4 +1,4 @@ -import { getCurrentHub } from '@sentry/core'; +import { getClient } from '@sentry/core'; import type { Breadcrumb, BreadcrumbHint, @@ -26,7 +26,7 @@ interface ExtendedNetworkBreadcrumbsOptions extends ReplayNetworkOptions { * (enriching it with further data that is _not_ added to the regular breadcrumbs) */ export function handleNetworkBreadcrumbs(replay: ReplayContainer): void { - const client = getCurrentHub().getClient(); + const client = getClient(); try { const textEncoder = new TextEncoder(); diff --git a/packages/replay/src/integration.ts b/packages/replay/src/integration.ts index 559b80532c77..b94907d44938 100644 --- a/packages/replay/src/integration.ts +++ b/packages/replay/src/integration.ts @@ -1,4 +1,4 @@ -import { getCurrentHub } from '@sentry/core'; +import { getClient } from '@sentry/core'; import type { BrowserClientReplayOptions, Integration } from '@sentry/types'; import { dropUndefinedKeys, isBrowser } from '@sentry/utils'; @@ -343,7 +343,7 @@ Sentry.init({ replaysOnErrorSampleRate: ${errorSampleRate} })`, /** Parse Replay-related options from SDK options */ function loadReplayOptionsFromClient(initialOptions: InitialReplayPluginOptions): ReplayPluginOptions { - const client = getCurrentHub().getClient(); + const client = getClient(); const opt = client && (client.getOptions() as BrowserClientReplayOptions); const finalOptions = { sessionSampleRate: 0, errorSampleRate: 0, ...dropUndefinedKeys(initialOptions) }; diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 8f185d5133ca..f4368c1d0930 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -1,6 +1,6 @@ /* eslint-disable max-lines */ // TODO: We might want to split this file up import { EventType, record } from '@sentry-internal/rrweb'; -import { captureException, getCurrentHub } from '@sentry/core'; +import { captureException, getClient, getCurrentHub } from '@sentry/core'; import type { ReplayRecordingMode, Transaction } from '@sentry/types'; import { logger } from '@sentry/utils'; @@ -1107,7 +1107,7 @@ export class ReplayContainer implements ReplayContainerInterface { // In this case, we want to completely stop the replay - otherwise, we may get inconsistent segments void this.stop({ reason: 'sendReplay' }); - const client = getCurrentHub().getClient(); + const client = getClient(); if (client) { client.recordDroppedEvent('send_error', 'replay'); diff --git a/packages/replay/src/util/addEvent.ts b/packages/replay/src/util/addEvent.ts index b5b6287034a9..fcfd13b3a10e 100644 --- a/packages/replay/src/util/addEvent.ts +++ b/packages/replay/src/util/addEvent.ts @@ -1,5 +1,5 @@ import { EventType } from '@sentry-internal/rrweb'; -import { getCurrentHub } from '@sentry/core'; +import { getClient } from '@sentry/core'; import { logger } from '@sentry/utils'; import { EventBufferSizeExceededError } from '../eventBuffer/error'; @@ -80,7 +80,7 @@ async function _addEvent( __DEBUG_BUILD__ && logger.error(error); await replay.stop({ reason }); - const client = getCurrentHub().getClient(); + const client = getClient(); if (client) { client.recordDroppedEvent('internal_sdk_error', 'replay'); diff --git a/packages/replay/src/util/addGlobalListeners.ts b/packages/replay/src/util/addGlobalListeners.ts index bf133c3e2130..cb7fbb75c00f 100644 --- a/packages/replay/src/util/addGlobalListeners.ts +++ b/packages/replay/src/util/addGlobalListeners.ts @@ -1,5 +1,5 @@ import type { BaseClient } from '@sentry/core'; -import { addGlobalEventProcessor, getCurrentHub } from '@sentry/core'; +import { addGlobalEventProcessor, getClient, getCurrentHub } from '@sentry/core'; import type { Client, DynamicSamplingContext } from '@sentry/types'; import { addInstrumentationHandler } from '@sentry/utils'; @@ -17,7 +17,7 @@ import type { ReplayContainer } from '../types'; export function addGlobalListeners(replay: ReplayContainer): void { // Listeners from core SDK // const scope = getCurrentHub().getScope(); - const client = getCurrentHub().getClient(); + const client = getClient(); scope.addScopeListener(handleScopeListener(replay)); addInstrumentationHandler('dom', handleDomListener(replay)); diff --git a/packages/replay/test/integration/coreHandlers/handleAfterSendEvent.test.ts b/packages/replay/test/integration/coreHandlers/handleAfterSendEvent.test.ts index cfb03073d12e..3cb668a83a67 100644 --- a/packages/replay/test/integration/coreHandlers/handleAfterSendEvent.test.ts +++ b/packages/replay/test/integration/coreHandlers/handleAfterSendEvent.test.ts @@ -1,4 +1,4 @@ -import { getCurrentHub } from '@sentry/core'; +import { getClient } from '@sentry/core'; import type { ErrorEvent, Event } from '@sentry/types'; import { UNABLE_TO_SEND_REPLAY } from '../../../src/constants'; @@ -152,7 +152,7 @@ describe('Integration | coreHandlers | handleAfterSendEvent', () => { }, })); - const client = getCurrentHub().getClient()!; + const client = getClient()!; // @ts-expect-error make sure to remove this delete client.getTransport()!.send.__sentry__baseTransport__; @@ -186,7 +186,7 @@ describe('Integration | coreHandlers | handleAfterSendEvent', () => { }, })); - const mockSend = getCurrentHub().getClient()!.getTransport()!.send as unknown as jest.SpyInstance; + const mockSend = getClient()!.getTransport()!.send as unknown as jest.SpyInstance; const error1 = Error({ event_id: 'err1', tags: { replayId: 'replayid1' } }); @@ -225,7 +225,7 @@ describe('Integration | coreHandlers | handleAfterSendEvent', () => { }, })); - const mockSend = getCurrentHub().getClient()!.getTransport()!.send as unknown as jest.SpyInstance; + const mockSend = getClient()!.getTransport()!.send as unknown as jest.SpyInstance; const error1 = Error({ event_id: 'err1' }); @@ -259,7 +259,7 @@ describe('Integration | coreHandlers | handleAfterSendEvent', () => { }, })); - const mockSend = getCurrentHub().getClient()!.getTransport()!.send as unknown as jest.SpyInstance; + const mockSend = getClient()!.getTransport()!.send as unknown as jest.SpyInstance; const profileEvent: Event = { type: 'profile' }; const replayEvent: Event = { type: 'replay_event' }; @@ -294,7 +294,7 @@ describe('Integration | coreHandlers | handleAfterSendEvent', () => { }, })); - const mockSend = getCurrentHub().getClient()!.getTransport()!.send as unknown as jest.SpyInstance; + const mockSend = getClient()!.getTransport()!.send as unknown as jest.SpyInstance; const error1 = Error({ event_id: 'err1' }); @@ -328,7 +328,7 @@ describe('Integration | coreHandlers | handleAfterSendEvent', () => { }, })); - const mockSend = getCurrentHub().getClient()!.getTransport()!.send as unknown as jest.SpyInstance; + const mockSend = getClient()!.getTransport()!.send as unknown as jest.SpyInstance; const error1: ErrorEvent = { event_id: 'err1', type: undefined }; @@ -362,7 +362,7 @@ describe('Integration | coreHandlers | handleAfterSendEvent', () => { }, })); - const mockSend = getCurrentHub().getClient()!.getTransport()!.send as unknown as jest.SpyInstance; + const mockSend = getClient()!.getTransport()!.send as unknown as jest.SpyInstance; const error1 = Error({ event_id: 'err1', message: UNABLE_TO_SEND_REPLAY }); @@ -396,7 +396,7 @@ describe('Integration | coreHandlers | handleAfterSendEvent', () => { }, })); - const mockSend = getCurrentHub().getClient()!.getTransport()!.send as unknown as jest.SpyInstance; + const mockSend = getClient()!.getTransport()!.send as unknown as jest.SpyInstance; const error1 = Error({ event_id: 'err1', tags: { replayId: 'replayid1' } }); @@ -429,7 +429,7 @@ describe('Integration | coreHandlers | handleAfterSendEvent', () => { }, })); - const mockSend = getCurrentHub().getClient()!.getTransport()!.send as unknown as jest.SpyInstance; + const mockSend = getClient()!.getTransport()!.send as unknown as jest.SpyInstance; const handler = handleAfterSendEvent(replay); diff --git a/packages/replay/test/integration/errorSampleRate.test.ts b/packages/replay/test/integration/errorSampleRate.test.ts index fadcaa568f25..f4be5232cffe 100644 --- a/packages/replay/test/integration/errorSampleRate.test.ts +++ b/packages/replay/test/integration/errorSampleRate.test.ts @@ -1,4 +1,4 @@ -import { captureException, getCurrentHub } from '@sentry/core'; +import { captureException, getClient } from '@sentry/core'; import { BUFFER_CHECKOUT_TIME, @@ -718,7 +718,7 @@ describe('Integration | errorSampleRate', () => { // Now wait after session expires - should stop recording mockRecord.takeFullSnapshot.mockClear(); - (getCurrentHub().getClient()!.getTransport()!.send as unknown as jest.SpyInstance).mockClear(); + (getClient()!.getTransport()!.send as unknown as jest.SpyInstance).mockClear(); expect(replay).not.toHaveLastSentReplay(); @@ -786,7 +786,7 @@ describe('Integration | errorSampleRate', () => { // Now wait after session expires - should stop recording mockRecord.takeFullSnapshot.mockClear(); - (getCurrentHub().getClient()!.getTransport()!.send as unknown as jest.SpyInstance).mockClear(); + (getClient()!.getTransport()!.send as unknown as jest.SpyInstance).mockClear(); jest.advanceTimersByTime(MAX_REPLAY_DURATION); await new Promise(process.nextTick); diff --git a/packages/replay/test/integration/events.test.ts b/packages/replay/test/integration/events.test.ts index 1b8b4726a778..7a3d6e920a9e 100644 --- a/packages/replay/test/integration/events.test.ts +++ b/packages/replay/test/integration/events.test.ts @@ -1,4 +1,4 @@ -import { getCurrentHub } from '@sentry/core'; +import { getClient } from '@sentry/core'; import { WINDOW } from '../../src/constants'; import type { ReplayContainer } from '../../src/replay'; @@ -36,7 +36,7 @@ describe('Integration | events', () => { }, })); - mockTransportSend = jest.spyOn(getCurrentHub().getClient()!.getTransport()!, 'send'); + mockTransportSend = jest.spyOn(getClient()!.getTransport()!, 'send'); // Create a new session and clear mocks because a segment (from initial // checkout) will have already been uploaded by the time the tests run diff --git a/packages/serverless/src/index.ts b/packages/serverless/src/index.ts index 3fc9074b224c..403e989e6a96 100644 --- a/packages/serverless/src/index.ts +++ b/packages/serverless/src/index.ts @@ -26,6 +26,7 @@ export { createTransport, getActiveTransaction, getCurrentHub, + getClient, getHubFromCarrier, makeMain, setContext, diff --git a/packages/sveltekit/src/server/index.ts b/packages/sveltekit/src/server/index.ts index b595324c2e4c..efaae15cbf02 100644 --- a/packages/sveltekit/src/server/index.ts +++ b/packages/sveltekit/src/server/index.ts @@ -19,6 +19,7 @@ export { getActiveTransaction, getHubFromCarrier, getCurrentHub, + getClient, Hub, makeMain, Scope, diff --git a/packages/sveltekit/test/client/sdk.test.ts b/packages/sveltekit/test/client/sdk.test.ts index b965e37538da..fafaa941f642 100644 --- a/packages/sveltekit/test/client/sdk.test.ts +++ b/packages/sveltekit/test/client/sdk.test.ts @@ -1,4 +1,4 @@ -import { getCurrentHub } from '@sentry/core'; +import { getClient, getCurrentHub } from '@sentry/core'; import type { BrowserClient } from '@sentry/svelte'; import * as SentrySvelte from '@sentry/svelte'; import { SDK_VERSION, WINDOW } from '@sentry/svelte'; @@ -62,7 +62,7 @@ describe('Sentry client SDK', () => { }); const integrationsToInit = svelteInit.mock.calls[0][0].integrations; - const browserTracing = (getCurrentHub().getClient() as BrowserClient)?.getIntegrationById('BrowserTracing'); + const browserTracing = getClient()?.getIntegrationById('BrowserTracing'); expect(integrationsToInit).toContainEqual(expect.objectContaining({ name: 'BrowserTracing' })); expect(browserTracing).toBeDefined(); @@ -78,7 +78,7 @@ describe('Sentry client SDK', () => { }); const integrationsToInit = svelteInit.mock.calls[0][0].integrations; - const browserTracing = (getCurrentHub().getClient() as BrowserClient)?.getIntegrationById('BrowserTracing'); + const browserTracing = getClient()?.getIntegrationById('BrowserTracing'); expect(integrationsToInit).not.toContainEqual(expect.objectContaining({ name: 'BrowserTracing' })); expect(browserTracing).toBeUndefined(); @@ -97,7 +97,7 @@ describe('Sentry client SDK', () => { }); const integrationsToInit = svelteInit.mock.calls[0][0].integrations; - const browserTracing = (getCurrentHub().getClient() as BrowserClient)?.getIntegrationById('BrowserTracing'); + const browserTracing = getClient()?.getIntegrationById('BrowserTracing'); expect(integrationsToInit).not.toContainEqual(expect.objectContaining({ name: 'BrowserTracing' })); expect(browserTracing).toBeUndefined(); @@ -115,9 +115,7 @@ describe('Sentry client SDK', () => { const integrationsToInit = svelteInit.mock.calls[0][0].integrations; - const browserTracing = (getCurrentHub().getClient() as BrowserClient)?.getIntegrationById( - 'BrowserTracing', - ) as BrowserTracing; + const browserTracing = getClient()?.getIntegrationById('BrowserTracing') as BrowserTracing; const options = browserTracing.options; expect(integrationsToInit).toContainEqual(expect.objectContaining({ name: 'BrowserTracing' })); diff --git a/packages/vercel-edge/src/index.ts b/packages/vercel-edge/src/index.ts index 4f9b81345203..fcb09ebd3094 100644 --- a/packages/vercel-edge/src/index.ts +++ b/packages/vercel-edge/src/index.ts @@ -38,6 +38,7 @@ export { getActiveTransaction, getHubFromCarrier, getCurrentHub, + getClient, Hub, lastEventId, makeMain, From 1ae365e9923d5e23770bc9fbb0d963afd0120d2d Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 22 Nov 2023 16:33:31 +0100 Subject: [PATCH 2/2] fix linting --- packages/core/src/baseclient.ts | 2 +- packages/node-experimental/src/integrations/http.ts | 2 +- packages/node-experimental/src/integrations/node-fetch.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index cd440b376655..915bafffa9bc 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -13,6 +13,7 @@ import type { EventDropReason, EventHint, EventProcessor, + FeedbackEvent, Integration, IntegrationClass, Outcome, @@ -27,7 +28,6 @@ import type { Transport, TransportMakeRequestResponse, } from '@sentry/types'; -import type { FeedbackEvent } from '@sentry/types'; import { addItemToEnvelope, checkOrSetAlreadyCaught, diff --git a/packages/node-experimental/src/integrations/http.ts b/packages/node-experimental/src/integrations/http.ts index f21aa9507395..4eb0308c6bd0 100644 --- a/packages/node-experimental/src/integrations/http.ts +++ b/packages/node-experimental/src/integrations/http.ts @@ -3,7 +3,7 @@ import { SpanKind } from '@opentelemetry/api'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'; import { hasTracingEnabled, isSentryRequestUrl } from '@sentry/core'; -import { _INTERNAL, getClient, getSpanKind, setSpanMetadata, getCurrentHub } from '@sentry/opentelemetry'; +import { _INTERNAL, getClient, getCurrentHub, getSpanKind, setSpanMetadata } from '@sentry/opentelemetry'; import type { EventProcessor, Hub, Integration } from '@sentry/types'; import { stringMatchesSomePattern } from '@sentry/utils'; import type { ClientRequest, IncomingMessage, ServerResponse } from 'http'; diff --git a/packages/node-experimental/src/integrations/node-fetch.ts b/packages/node-experimental/src/integrations/node-fetch.ts index 53d15dbce6c3..54d67f33f4c2 100644 --- a/packages/node-experimental/src/integrations/node-fetch.ts +++ b/packages/node-experimental/src/integrations/node-fetch.ts @@ -2,7 +2,7 @@ import type { Span } from '@opentelemetry/api'; import { SpanKind } from '@opentelemetry/api'; import type { Instrumentation } from '@opentelemetry/instrumentation'; import { hasTracingEnabled } from '@sentry/core'; -import { _INTERNAL, getCurrentHub, getSpanKind, getClient } from '@sentry/opentelemetry'; +import { _INTERNAL, getClient, getCurrentHub, getSpanKind } from '@sentry/opentelemetry'; import type { Integration } from '@sentry/types'; import type { NodeExperimentalClient } from '../types';