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