diff --git a/MIGRATION.md b/MIGRATION.md
index a5c4677541fc..30eb4e4ca1f4 100644
--- a/MIGRATION.md
+++ b/MIGRATION.md
@@ -52,7 +52,12 @@ Sentry.init({
In v8, the Hub class will be removed. The following methods are therefore deprecated:
-- `hub.shouldSendDefaultPii()`: Access Sentry client option via `Sentry.getClient().getOptions().sendDefaultPii` instead
+* `hub.startTransaction()`: See [Deprecation of `startTransaction`](#deprecate-starttransaction)
+* `hub.lastEventId()`: See [Deprecation of `lastEventId`](#deprecate-sentrylasteventid-and-hublasteventid)
+* `hub.startSession()`: Use top-level `Sentry.startSession()` instead
+* `hub.endSession()`: Use top-level `Sentry.endSession()` instead
+* `hub.captureSession()`: Use top-level `Sentry.captureSession()` instead
+* `hub.shouldSendDefaultPii()`: Access Sentry client option via `Sentry.getClient().getOptions().sendDefaultPii` instead
## Deprecated fields on `Span` and `Transaction`
diff --git a/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/init.js b/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/init.js
new file mode 100644
index 000000000000..4958e35f2198
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/init.js
@@ -0,0 +1,14 @@
+import * as Sentry from '@sentry/browser';
+
+window.Sentry = Sentry;
+
+Sentry.init({
+ dsn: 'https://public@dsn.ingest.sentry.io/1337',
+ release: '0.1',
+ // intentionally disabling this, we want to leverage the deprecated hub API
+ autoSessionTracking: false,
+});
+
+// simulate old startSessionTracking behavior
+Sentry.getCurrentHub().startSession({ ignoreDuration: true });
+Sentry.getCurrentHub().captureSession();
diff --git a/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/template.html b/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/template.html
new file mode 100644
index 000000000000..77906444cbce
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/template.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+ Navigate
+
+
diff --git a/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/test.ts b/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/test.ts
new file mode 100644
index 000000000000..8a48f161c93b
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/test.ts
@@ -0,0 +1,39 @@
+import type { Route } from '@playwright/test';
+import { expect } from '@playwright/test';
+import type { SessionContext } from '@sentry/types';
+
+import { sentryTest } from '../../../utils/fixtures';
+import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers';
+
+sentryTest('should start a new session on pageload.', async ({ getLocalTestPath, page }) => {
+ const url = await getLocalTestPath({ testDir: __dirname });
+ const session = await getFirstSentryEnvelopeRequest(page, url);
+
+ expect(session).toBeDefined();
+ expect(session.init).toBe(true);
+ expect(session.errors).toBe(0);
+ expect(session.status).toBe('ok');
+});
+
+sentryTest('should start a new session with navigation.', async ({ getLocalTestPath, page, browserName }) => {
+ // Navigations get CORS error on Firefox and WebKit as we're using `file://` protocol.
+ if (browserName !== 'chromium') {
+ sentryTest.skip();
+ }
+
+ const url = await getLocalTestPath({ testDir: __dirname });
+ await page.route('**/foo', (route: Route) => route.fulfill({ path: `${__dirname}/dist/index.html` }));
+
+ const initSession = await getFirstSentryEnvelopeRequest(page, url);
+
+ await page.click('#navigate');
+
+ const newSession = await getFirstSentryEnvelopeRequest(page, url);
+
+ expect(newSession).toBeDefined();
+ expect(newSession.init).toBe(true);
+ expect(newSession.errors).toBe(0);
+ expect(newSession.status).toBe('ok');
+ expect(newSession.sid).toBeDefined();
+ expect(initSession.sid).not.toBe(newSession.sid);
+});
diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts
index 579bb57e9698..451cce98e3b7 100644
--- a/packages/browser/src/sdk.ts
+++ b/packages/browser/src/sdk.ts
@@ -1,11 +1,13 @@
import type { Hub } from '@sentry/core';
import {
Integrations as CoreIntegrations,
+ captureSession,
getClient,
getCurrentHub,
getIntegrationsToSetup,
getReportDialogEndpoint,
initAndBind,
+ startSession,
} from '@sentry/core';
import type { UserFeedback } from '@sentry/types';
import {
@@ -250,11 +252,6 @@ export function wrap(fn: (...args: any) => any): any {
return internalWrap(fn)();
}
-function startSessionOnHub(hub: Hub): void {
- hub.startSession({ ignoreDuration: true });
- hub.captureSession();
-}
-
/**
* Enable automatic Session Tracking for the initial page load.
*/
@@ -264,29 +261,19 @@ function startSessionTracking(): void {
return;
}
- const hub = getCurrentHub();
-
- // The only way for this to be false is for there to be a version mismatch between @sentry/browser (>= 6.0.0) and
- // @sentry/hub (< 5.27.0). In the simple case, there won't ever be such a mismatch, because the two packages are
- // pinned at the same version in package.json, but there are edge cases where it's possible. See
- // https://github.com/getsentry/sentry-javascript/issues/3207 and
- // https://github.com/getsentry/sentry-javascript/issues/3234 and
- // https://github.com/getsentry/sentry-javascript/issues/3278.
- if (!hub.captureSession) {
- return;
- }
-
// The session duration for browser sessions does not track a meaningful
// concept that can be used as a metric.
// Automatically captured sessions are akin to page views, and thus we
// discard their duration.
- startSessionOnHub(hub);
+ startSession({ ignoreDuration: true });
+ captureSession();
// We want to create a session for every navigation as well
addHistoryInstrumentationHandler(({ from, to }) => {
// Don't create an additional session for the initial route or if the location did not change
if (from !== undefined && from !== to) {
- startSessionOnHub(getCurrentHub());
+ startSession({ ignoreDuration: true });
+ captureSession();
}
});
}
diff --git a/packages/core/src/exports.ts b/packages/core/src/exports.ts
index 09989215ef3e..bc37a633c16e 100644
--- a/packages/core/src/exports.ts
+++ b/packages/core/src/exports.ts
@@ -12,17 +12,21 @@ import type {
FinishedCheckIn,
MonitorConfig,
Primitive,
+ Session,
+ SessionContext,
Severity,
SeverityLevel,
TransactionContext,
User,
} from '@sentry/types';
-import { isThenable, logger, timestampInSeconds, uuid4 } from '@sentry/utils';
+import { GLOBAL_OBJ, isThenable, logger, timestampInSeconds, uuid4 } from '@sentry/utils';
+import { DEFAULT_ENVIRONMENT } from './constants';
import { DEBUG_BUILD } from './debug-build';
import type { Hub } from './hub';
-import { getCurrentHub } from './hub';
+import { getCurrentHub, getIsolationScope } from './hub';
import type { Scope } from './scope';
+import { closeSession, makeSession, updateSession } from './session';
import type { ExclusiveEventHintOrCaptureContext } from './utils/prepareEvent';
import { parseEventHintOrCaptureContext } from './utils/prepareEvent';
@@ -322,3 +326,99 @@ export function getClient(): C | undefined {
export function getCurrentScope(): Scope {
return getCurrentHub().getScope();
}
+
+/**
+ * Start a session on the current isolation scope.
+ *
+ * @param context (optional) additional properties to be applied to the returned session object
+ *
+ * @returns the new active session
+ */
+export function startSession(context?: SessionContext): Session {
+ const client = getClient();
+ const isolationScope = getIsolationScope();
+ const currentScope = getCurrentScope();
+
+ const { release, environment = DEFAULT_ENVIRONMENT } = (client && client.getOptions()) || {};
+
+ // Will fetch userAgent if called from browser sdk
+ const { userAgent } = GLOBAL_OBJ.navigator || {};
+
+ const session = makeSession({
+ release,
+ environment,
+ user: isolationScope.getUser(),
+ ...(userAgent && { userAgent }),
+ ...context,
+ });
+
+ // End existing session if there's one
+ const currentSession = isolationScope.getSession();
+ if (currentSession && currentSession.status === 'ok') {
+ updateSession(currentSession, { status: 'exited' });
+ }
+
+ endSession();
+
+ // Afterwards we set the new session on the scope
+ isolationScope.setSession(session);
+
+ // TODO (v8): Remove this and only use the isolation scope(?).
+ // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession()
+ currentScope.setSession(session);
+
+ return session;
+}
+
+/**
+ * End the session on the current isolation scope.
+ */
+export function endSession(): void {
+ const isolationScope = getIsolationScope();
+ const currentScope = getCurrentScope();
+
+ const session = isolationScope.getSession();
+ if (session) {
+ closeSession(session);
+ }
+ _sendSessionUpdate();
+
+ // the session is over; take it off of the scope
+ isolationScope.setSession();
+
+ // TODO (v8): Remove this and only use the isolation scope(?).
+ // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession()
+ currentScope.setSession();
+}
+
+/**
+ * Sends the current Session on the scope
+ */
+function _sendSessionUpdate(): void {
+ const isolationScope = getIsolationScope();
+ const currentScope = getCurrentScope();
+ const client = getClient();
+ // TODO (v8): Remove currentScope and only use the isolation scope(?).
+ // For v7 though, we can't "soft-break" people using getCurrentHub().getScope().setSession()
+ const session = currentScope.getSession() || isolationScope.getSession();
+ if (session && client && client.captureSession) {
+ client.captureSession(session);
+ }
+}
+
+/**
+ * Sends the current session on the scope to Sentry
+ *
+ * @param end If set the session will be marked as exited and removed from the scope.
+ * Defaults to `false`.
+ */
+export function captureSession(end: boolean = false): void {
+ // both send the update and pull the session from the scope
+ if (end) {
+ endSession();
+ return;
+ }
+
+ // only send the update
+ _sendSessionUpdate();
+}
diff --git a/packages/core/src/hub.ts b/packages/core/src/hub.ts
index 1db3b01e7b0e..9012ab057e92 100644
--- a/packages/core/src/hub.ts
+++ b/packages/core/src/hub.ts
@@ -487,10 +487,13 @@ Sentry.init({...});
/**
* @inheritDoc
+ *
+ * @deprecated Use top level `captureSession` instead.
*/
public captureSession(endSession: boolean = false): void {
// both send the update and pull the session from the scope
if (endSession) {
+ // eslint-disable-next-line deprecation/deprecation
return this.endSession();
}
@@ -500,6 +503,7 @@ Sentry.init({...});
/**
* @inheritDoc
+ * @deprecated Use top level `endSession` instead.
*/
public endSession(): void {
const layer = this.getStackTop();
@@ -516,6 +520,7 @@ Sentry.init({...});
/**
* @inheritDoc
+ * @deprecated Use top level `startSession` instead.
*/
public startSession(context?: SessionContext): Session {
const { scope, client } = this.getStackTop();
@@ -537,6 +542,7 @@ Sentry.init({...});
if (currentSession && currentSession.status === 'ok') {
updateSession(currentSession, { status: 'exited' });
}
+ // eslint-disable-next-line deprecation/deprecation
this.endSession();
// Afterwards we set the new session on the scope
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 2c423f0744c3..1585e119d249 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -30,6 +30,9 @@ export {
withScope,
getClient,
getCurrentScope,
+ startSession,
+ endSession,
+ captureSession,
} from './exports';
export {
getCurrentHub,
diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts
index 4c82ef60ffd4..4d3786bab9c5 100644
--- a/packages/core/src/session.ts
+++ b/packages/core/src/session.ts
@@ -1,6 +1,5 @@
import type { SerializedSession, Session, SessionContext, SessionStatus } from '@sentry/types';
import { dropUndefinedKeys, timestampInSeconds, uuid4 } from '@sentry/utils';
-
/**
* Creates a new `Session` object by setting certain default parameters. If optional @param context
* is passed, the passed properties are applied to the session object.
diff --git a/packages/core/test/lib/exports.test.ts b/packages/core/test/lib/exports.test.ts
index 7a4ec6987dd1..c16073255030 100644
--- a/packages/core/test/lib/exports.test.ts
+++ b/packages/core/test/lib/exports.test.ts
@@ -1,4 +1,14 @@
-import { Hub, Scope, getCurrentScope, makeMain, withScope } from '../../src';
+import {
+ Hub,
+ Scope,
+ captureSession,
+ endSession,
+ getCurrentScope,
+ getIsolationScope,
+ makeMain,
+ startSession,
+ withScope,
+} from '../../src';
import { TestClient, getDefaultTestClientOptions } from '../mocks/client';
function getTestClient(): TestClient {
@@ -125,3 +135,94 @@ describe('withScope', () => {
expect(getCurrentScope()).toBe(scope1);
});
});
+
+describe('session APIs', () => {
+ beforeEach(() => {
+ const client = getTestClient();
+ const hub = new Hub(client);
+ makeMain(hub);
+ });
+
+ describe('startSession', () => {
+ it('starts a session', () => {
+ const session = startSession();
+
+ expect(session).toMatchObject({
+ status: 'ok',
+ errors: 0,
+ init: true,
+ environment: 'production',
+ ignoreDuration: false,
+ sid: expect.any(String),
+ did: undefined,
+ timestamp: expect.any(Number),
+ started: expect.any(Number),
+ duration: expect.any(Number),
+ toJSON: expect.any(Function),
+ });
+ });
+
+ it('ends a previously active session and removes it from the scope', () => {
+ const session1 = startSession();
+
+ expect(session1.status).toBe('ok');
+ expect(getIsolationScope().getSession()).toBe(session1);
+
+ const session2 = startSession();
+
+ expect(session2.status).toBe('ok');
+ expect(session1.status).toBe('exited');
+ expect(getIsolationScope().getSession()).toBe(session2);
+ });
+ });
+
+ describe('endSession', () => {
+ it('ends a session and removes it from the scope', () => {
+ const session = startSession();
+
+ expect(session.status).toBe('ok');
+ expect(getIsolationScope().getSession()).toBe(session);
+
+ endSession();
+
+ expect(session.status).toBe('exited');
+ expect(getIsolationScope().getSession()).toBe(undefined);
+ });
+ });
+
+ describe('captureSession', () => {
+ it('captures a session without ending it by default', () => {
+ const session = startSession({ release: '1.0.0' });
+
+ expect(session.status).toBe('ok');
+ expect(session.init).toBe(true);
+ expect(getIsolationScope().getSession()).toBe(session);
+
+ captureSession();
+
+ // this flag indicates the session was sent via BaseClient
+ expect(session.init).toBe(false);
+
+ // session is still active and on the scope
+ expect(session.status).toBe('ok');
+ expect(getIsolationScope().getSession()).toBe(session);
+ });
+
+ it('captures a session and ends it if end is `true`', () => {
+ const session = startSession({ release: '1.0.0' });
+
+ expect(session.status).toBe('ok');
+ expect(session.init).toBe(true);
+ expect(getIsolationScope().getSession()).toBe(session);
+
+ captureSession(true);
+
+ // this flag indicates the session was sent via BaseClient
+ expect(session.init).toBe(false);
+
+ // session is still active and on the scope
+ expect(session.status).toBe('exited');
+ expect(getIsolationScope().getSession()).toBe(undefined);
+ });
+ });
+});
diff --git a/packages/hub/test/hub.test.ts b/packages/hub/test/hub.test.ts
index fbdc3993b989..08ec6a22130a 100644
--- a/packages/hub/test/hub.test.ts
+++ b/packages/hub/test/hub.test.ts
@@ -3,6 +3,7 @@
import type { Client, Event, EventType } from '@sentry/types';
+import { getCurrentScope, makeMain } from '@sentry/core';
import { Hub, Scope, getCurrentHub } from '../src';
const clientFn: any = jest.fn();
@@ -18,6 +19,7 @@ function makeClient() {
getIntegration: jest.fn(),
setupIntegrations: jest.fn(),
captureMessage: jest.fn(),
+ captureSession: jest.fn(),
} as unknown as Client;
}
@@ -453,4 +455,102 @@ describe('Hub', () => {
expect(hub.shouldSendDefaultPii()).toBe(true);
});
});
+
+ describe('session APIs', () => {
+ beforeEach(() => {
+ const testClient = makeClient();
+ const hub = new Hub(testClient);
+ makeMain(hub);
+ });
+
+ describe('startSession', () => {
+ it('starts a session', () => {
+ const testClient = makeClient();
+ const hub = new Hub(testClient);
+ makeMain(hub);
+ const session = hub.startSession();
+
+ expect(session).toMatchObject({
+ status: 'ok',
+ errors: 0,
+ init: true,
+ environment: 'production',
+ ignoreDuration: false,
+ sid: expect.any(String),
+ did: undefined,
+ timestamp: expect.any(Number),
+ started: expect.any(Number),
+ duration: expect.any(Number),
+ toJSON: expect.any(Function),
+ });
+ });
+
+ it('ends a previously active session and removes it from the scope', () => {
+ const testClient = makeClient();
+ const hub = new Hub(testClient);
+ makeMain(hub);
+
+ const session1 = hub.startSession();
+
+ expect(session1.status).toBe('ok');
+ expect(getCurrentScope().getSession()).toBe(session1);
+
+ const session2 = hub.startSession();
+
+ expect(session2.status).toBe('ok');
+ expect(session1.status).toBe('exited');
+ expect(getCurrentHub().getScope().getSession()).toBe(session2);
+ });
+ });
+
+ describe('endSession', () => {
+ it('ends a session and removes it from the scope', () => {
+ const testClient = makeClient();
+ const hub = new Hub(testClient);
+ makeMain(hub);
+
+ const session = hub.startSession();
+
+ expect(session.status).toBe('ok');
+ expect(getCurrentScope().getSession()).toBe(session);
+
+ hub.endSession();
+
+ expect(session.status).toBe('exited');
+ expect(getCurrentHub().getScope().getSession()).toBe(undefined);
+ });
+ });
+
+ describe('captureSession', () => {
+ it('captures a session without ending it by default', () => {
+ const testClient = makeClient();
+ const hub = new Hub(testClient);
+ makeMain(hub);
+
+ const session = hub.startSession();
+
+ expect(session.status).toBe('ok');
+ expect(getCurrentScope().getSession()).toBe(session);
+
+ hub.captureSession();
+
+ expect(testClient.captureSession).toHaveBeenCalledWith(expect.objectContaining({ status: 'ok' }));
+ });
+
+ it('captures a session and ends it if end is `true`', () => {
+ const testClient = makeClient();
+ const hub = new Hub(testClient);
+ makeMain(hub);
+
+ const session = hub.startSession();
+
+ expect(session.status).toBe('ok');
+ expect(hub.getScope().getSession()).toBe(session);
+
+ hub.captureSession(true);
+
+ expect(testClient.captureSession).toHaveBeenCalledWith(expect.objectContaining({ status: 'exited' }));
+ });
+ });
+ });
});
diff --git a/packages/node-experimental/src/sdk/api.ts b/packages/node-experimental/src/sdk/api.ts
index 71a08dd38552..15882a6f165a 100644
--- a/packages/node-experimental/src/sdk/api.ts
+++ b/packages/node-experimental/src/sdk/api.ts
@@ -1,7 +1,6 @@
// PUBLIC APIS
import { context } from '@opentelemetry/api';
-import { DEFAULT_ENVIRONMENT, closeSession, makeSession, updateSession } from '@sentry/core';
import type {
Breadcrumb,
BreadcrumbHint,
@@ -12,12 +11,11 @@ import type {
Extra,
Extras,
Primitive,
- Session,
Severity,
SeverityLevel,
User,
} from '@sentry/types';
-import { GLOBAL_OBJ, consoleSandbox, dateTimestampInSeconds } from '@sentry/utils';
+import { consoleSandbox, dateTimestampInSeconds } from '@sentry/utils';
import { getScopesFromContext, setScopesOnContext } from '../utils/contextData';
import type { ExclusiveEventHintOrCaptureContext } from '../utils/prepareEvent';
@@ -168,60 +166,3 @@ export function setContext(
): void {
getIsolationScope().setContext(name, context);
}
-
-/** Start a session on the current isolation scope. */
-export function startSession(context?: Session): Session {
- const client = getClient();
- const isolationScope = getIsolationScope();
-
- const { release, environment = DEFAULT_ENVIRONMENT } = client.getOptions();
-
- // Will fetch userAgent if called from browser sdk
- const { userAgent } = GLOBAL_OBJ.navigator || {};
-
- const session = makeSession({
- release,
- environment,
- user: isolationScope.getUser(),
- ...(userAgent && { userAgent }),
- ...context,
- });
-
- // End existing session if there's one
- const currentSession = isolationScope.getSession && isolationScope.getSession();
- if (currentSession && currentSession.status === 'ok') {
- updateSession(currentSession, { status: 'exited' });
- }
- endSession();
-
- // Afterwards we set the new session on the scope
- isolationScope.setSession(session);
-
- return session;
-}
-
-/** End the session on the current isolation scope. */
-export function endSession(): void {
- const isolationScope = getIsolationScope();
- const session = isolationScope.getSession();
- if (session) {
- closeSession(session);
- }
- _sendSessionUpdate();
-
- // the session is over; take it off of the scope
- isolationScope.setSession();
-}
-
-/**
- * Sends the current Session on the scope
- */
-function _sendSessionUpdate(): void {
- const scope = getCurrentScope();
- const client = getClient();
-
- const session = scope.getSession();
- if (session && client.captureSession) {
- client.captureSession(session);
- }
-}
diff --git a/packages/node-experimental/src/sdk/hub.ts b/packages/node-experimental/src/sdk/hub.ts
index b58548acb326..5de82086f387 100644
--- a/packages/node-experimental/src/sdk/hub.ts
+++ b/packages/node-experimental/src/sdk/hub.ts
@@ -10,11 +10,11 @@ import type {
TransactionContext,
} from '@sentry/types';
+import { endSession, startSession } from '@sentry/core';
import {
addBreadcrumb,
captureEvent,
configureScope,
- endSession,
getClient,
getCurrentScope,
lastEventId,
@@ -24,7 +24,6 @@ import {
setTag,
setTags,
setUser,
- startSession,
withScope,
} from './api';
import { callExtensionMethod, getGlobalCarrier } from './globals';
@@ -121,6 +120,7 @@ export function getCurrentHub(): Hub {
captureSession(endSession?: boolean): void {
// both send the update and pull the session from the scope
if (endSession) {
+ // eslint-disable-next-line deprecation/deprecation
return this.endSession();
}
diff --git a/packages/node-experimental/src/sdk/init.ts b/packages/node-experimental/src/sdk/init.ts
index 821757a9a246..0f60bccd343c 100644
--- a/packages/node-experimental/src/sdk/init.ts
+++ b/packages/node-experimental/src/sdk/init.ts
@@ -1,4 +1,4 @@
-import { getIntegrationsToSetup, hasTracingEnabled } from '@sentry/core';
+import { endSession, getIntegrationsToSetup, hasTracingEnabled, startSession } from '@sentry/core';
import {
Integrations,
defaultIntegrations as defaultNodeIntegrations,
@@ -22,7 +22,7 @@ import { Http } from '../integrations/http';
import { NodeFetch } from '../integrations/node-fetch';
import { setOpenTelemetryContextAsyncContextStrategy } from '../otel/asyncContextStrategy';
import type { NodeExperimentalClientOptions, NodeExperimentalOptions } from '../types';
-import { endSession, getClient, getCurrentScope, getGlobalScope, getIsolationScope, startSession } from './api';
+import { getClient, getCurrentScope, getGlobalScope, getIsolationScope } from './api';
import { NodeExperimentalClient } from './client';
import { getGlobalCarrier } from './globals';
import { setLegacyHubOnCarrier } from './hub';
diff --git a/packages/node/src/sdk.ts b/packages/node/src/sdk.ts
index c9a1c108dfdd..88a6b1a9074c 100644
--- a/packages/node/src/sdk.ts
+++ b/packages/node/src/sdk.ts
@@ -1,12 +1,14 @@
/* eslint-disable max-lines */
import {
Integrations as CoreIntegrations,
+ endSession,
getClient,
- getCurrentHub,
getCurrentScope,
getIntegrationsToSetup,
+ getIsolationScope,
getMainCarrier,
initAndBind,
+ startSession,
} from '@sentry/core';
import type { SessionStatus, StackParser } from '@sentry/types';
import {
@@ -244,20 +246,21 @@ export const defaultStackParser: StackParser = createStackParser(nodeStackLinePa
* Enable automatic Session Tracking for the node process.
*/
function startSessionTracking(): void {
- const hub = getCurrentHub();
- hub.startSession();
+ startSession();
// Emitted in the case of healthy sessions, error of `mechanism.handled: true` and unhandledrejections because
// The 'beforeExit' event is not emitted for conditions causing explicit termination,
// such as calling process.exit() or uncaught exceptions.
// Ref: https://nodejs.org/api/process.html#process_event_beforeexit
process.on('beforeExit', () => {
- const session = hub.getScope().getSession();
+ const session = getIsolationScope().getSession();
const terminalStates: SessionStatus[] = ['exited', 'crashed'];
// Only call endSession, if the Session exists on Scope and SessionStatus is not a
// Terminal Status i.e. Exited or Crashed because
// "When a session is moved away from ok it must not be updated anymore."
// Ref: https://develop.sentry.dev/sdk/sessions/
- if (session && !terminalStates.includes(session.status)) hub.endSession();
+ if (session && !terminalStates.includes(session.status)) {
+ endSession();
+ }
});
}
diff --git a/packages/types/src/hub.ts b/packages/types/src/hub.ts
index 17e839f3f46e..53d689a826bf 100644
--- a/packages/types/src/hub.ts
+++ b/packages/types/src/hub.ts
@@ -230,22 +230,29 @@ export interface Hub {
* @param context Optional properties of the new `Session`.
*
* @returns The session which was just started
+ *
+ * @deprecated Use top-level `startSession` instead.
*/
startSession(context?: Session): Session;
/**
* Ends the session that lives on the current scope and sends it to Sentry
+ *
+ * @deprecated Use top-level `endSession` instead.
*/
endSession(): void;
/**
* Sends the current session on the scope to Sentry
+ *
* @param endSession If set the session will be marked as exited and removed from the scope
+ *
+ * @deprecated Use top-level `captureSession` instead.
*/
captureSession(endSession?: boolean): void;
/**
- * Returns if default PII should be sent to Sentry and propagated in ourgoing requests
+ * Returns if default PII should be sent to Sentry and propagated in outgoing requests
* when Tracing is used.
*
* @deprecated Use top-level `getClient().getOptions().sendDefaultPii` instead. This function