Skip to content

Commit 656d7c4

Browse files
authored
ref(hub): Convert Session class to object and functions (#5054)
convert the `Session` class to a more FP style `Session` object with additional functions that replace the methods of the class. API-wise, this makes the following changes: * `new Session(context)` => `makeSession(context)` * `session.update(context)` => `updateSession(session, context)` * `session.close(status)` => `closeSession(session, status)` `session.toJSON()` is left untouched because this method is called when the Session object is serialized to the JSON object that's sent to the Sentry servers. Additionally, this modify the session-related interfaces. Interface `Session` now describes the session object while the `SessionContext` interface is used to make modifications to the session by calling `updateSession`. Note that `updateSession` and `closeSession` mutate the session object that's passed in as a parameter. I originally wanted to return a new, mutated, object and leave the original one untouched instead of changing it. However this is unfortunately not possible (without bigger modifications) as `BaseClient` makes a modification to a session after it's already passed to `sendSession` to keep it from getting re-sent as a new session.
1 parent 5beee11 commit 656d7c4

File tree

14 files changed

+241
-192
lines changed

14 files changed

+241
-192
lines changed

MIGRATION.md

+30
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,32 @@ changes in v7. They will be removed in the next major release which is why we st
292292
corresponding string literals. Here's how to adjust [`Severity`](#severity-severitylevel-and-severitylevels) and
293293
[`SpanStatus`](#spanstatus).
294294

295+
## Session Changes
296+
297+
Note: These changes are not relevant for the majority of Sentry users but if you are building an
298+
SDK on top of the Javascript SDK, you might need to make some adaptions.
299+
The internal `Session` class was refactored and replaced with a more functional approach in
300+
[#5054](https://github.com/getsentry/sentry-javascript/pull/5054).
301+
Instead of the class, we now export a `Session` interface from `@sentry/types` and three utility functions
302+
to create and update a `Session` object from `@sentry/hub`.
303+
This short example shows what has changed and how to deal with the new functions:
304+
305+
```js
306+
// New in v7:
307+
import { makeSession, updateSession, closeSession } from '@sentry/hub';
308+
309+
const session = makeSession({ release: 'v1.0' });
310+
updateSession(session, { environment: 'prod' });
311+
closeSession(session, 'ok');
312+
313+
// Before:
314+
import { Session } from '@sentry/hub';
315+
316+
const session = new Session({ release: 'v1.0' });
317+
session.update({ environment: 'prod' });
318+
session.close('ok');
319+
```
320+
295321
## General API Changes
296322

297323
For our efforts to reduce bundle size of the SDK we had to remove and refactor parts of the package which introduced a few changes to the API:
@@ -313,7 +339,11 @@ For our efforts to reduce bundle size of the SDK we had to remove and refactor p
313339
- Rename `UserAgent` integration to `HttpContext`. (see [#5027](https://github.com/getsentry/sentry-javascript/pull/5027))
314340
- Remove `SDK_NAME` export from `@sentry/browser`, `@sentry/node`, `@sentry/tracing` and `@sentry/vue` packages.
315341
- Removed `eventStatusFromHttpCode` to save on bundle size.
342+
<<<<<<< HEAD
316343
- Replace `BrowserTracing` `maxTransactionDuration` option with `finalTimeout` option
344+
- Replace `Session` class with a session object and functions (see [#5054](https://github.com/getsentry/sentry-javascript/pull/5054)).
345+
=======
346+
>>>>>>> 5c81e32c4 (Add "Session Changes" section to Migration docs)
317347
318348
## Sentry Angular SDK Changes
319349

packages/browser/src/exports.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export type {
1313
Stacktrace,
1414
Thread,
1515
User,
16+
Session,
1617
} from '@sentry/types';
1718

1819
export type { BrowserOptions } from './client';
@@ -31,7 +32,6 @@ export {
3132
Hub,
3233
makeMain,
3334
Scope,
34-
Session,
3535
startTransaction,
3636
SDK_VERSION,
3737
setContext,

packages/core/src/baseclient.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable max-lines */
2-
import { Scope, Session } from '@sentry/hub';
2+
import { Scope, updateSession } from '@sentry/hub';
33
import {
44
Client,
55
ClientOptions,
@@ -12,6 +12,7 @@ import {
1212
Integration,
1313
IntegrationClass,
1414
Outcome,
15+
Session,
1516
SessionAggregates,
1617
Severity,
1718
SeverityLevel,
@@ -199,7 +200,7 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
199200
} else {
200201
this.sendSession(session);
201202
// After sending, we set init false to indicate it's not the first occurrence
202-
session.update({ init: false });
203+
updateSession(session, { init: false });
203204
}
204205
}
205206

@@ -343,7 +344,7 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
343344
const shouldUpdateAndSend = (sessionNonTerminal && session.errors === 0) || (sessionNonTerminal && crashed);
344345

345346
if (shouldUpdateAndSend) {
346-
session.update({
347+
updateSession(session, {
347348
...(crashed && { status: 'crashed' }),
348349
errors: session.errors || Number(errored || crashed),
349350
});

packages/core/src/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ export {
2020
Hub,
2121
makeMain,
2222
Scope,
23-
Session,
2423
} from '@sentry/hub';
2524
export { getEnvelopeEndpointWithUrlEncodedAuth, getReportDialogEndpoint } from './api';
2625
export { BaseClient } from './baseclient';

packages/core/test/lib/base.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Hub, Scope, Session } from '@sentry/hub';
1+
import { Hub, makeSession, Scope } from '@sentry/hub';
22
import { Event, Span } from '@sentry/types';
33
import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils';
44

@@ -1327,7 +1327,7 @@ describe('BaseClient', () => {
13271327

13281328
const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN });
13291329
const client = new TestClient(options);
1330-
const session = new Session({ release: 'test' });
1330+
const session = makeSession({ release: 'test' });
13311331

13321332
client.captureSession(session);
13331333

@@ -1339,7 +1339,7 @@ describe('BaseClient', () => {
13391339

13401340
const options = getDefaultTestClientOptions({ enabled: false, dsn: PUBLIC_DSN });
13411341
const client = new TestClient(options);
1342-
const session = new Session({ release: 'test' });
1342+
const session = makeSession({ release: 'test' });
13431343

13441344
client.captureSession(session);
13451345

packages/core/test/mocks/client.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { Session } from '@sentry/hub';
2-
import { ClientOptions, Event, Integration, Outcome, Severity, SeverityLevel } from '@sentry/types';
1+
import { ClientOptions, Event, Integration, Outcome, Session, Severity, SeverityLevel } from '@sentry/types';
32
import { resolvedSyncPromise } from '@sentry/utils';
43

54
import { BaseClient } from '../../src/baseclient';

packages/hub/src/hub.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
Integration,
1313
IntegrationClass,
1414
Primitive,
15+
Session,
1516
SessionContext,
1617
Severity,
1718
SeverityLevel,
@@ -31,7 +32,7 @@ import {
3132

3233
import { IS_DEBUG_BUILD } from './flags';
3334
import { Scope } from './scope';
34-
import { Session } from './session';
35+
import { closeSession, makeSession, updateSession } from './session';
3536

3637
/**
3738
* API compatibility version of this hub.
@@ -395,7 +396,7 @@ export class Hub implements HubInterface {
395396
const scope = layer && layer.scope;
396397
const session = scope && scope.getSession();
397398
if (session) {
398-
session.close();
399+
closeSession(session);
399400
}
400401
this._sendSessionUpdate();
401402

@@ -416,7 +417,7 @@ export class Hub implements HubInterface {
416417
const global = getGlobalObject<{ navigator?: { userAgent?: string } }>();
417418
const { userAgent } = global.navigator || {};
418419

419-
const session = new Session({
420+
const session = makeSession({
420421
release,
421422
environment,
422423
...(scope && { user: scope.getUser() }),
@@ -428,7 +429,7 @@ export class Hub implements HubInterface {
428429
// End existing session if there's one
429430
const currentSession = scope.getSession && scope.getSession();
430431
if (currentSession && currentSession.status === 'ok') {
431-
currentSession.update({ status: 'exited' });
432+
updateSession(currentSession, { status: 'exited' });
432433
}
433434
this.endSession();
434435

@@ -446,7 +447,7 @@ export class Hub implements HubInterface {
446447
const { scope, client } = this.getStackTop();
447448
if (!scope) return;
448449

449-
const session = scope.getSession && scope.getSession();
450+
const session = scope.getSession();
450451
if (session) {
451452
if (client && client.captureSession) {
452453
client.captureSession(session);

packages/hub/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export type { Carrier, Layer } from './hub';
22

33
export { addGlobalEventProcessor, Scope } from './scope';
4-
export { Session } from './session';
4+
export { closeSession, makeSession, updateSession } from './session';
55
export { SessionFlusher } from './sessionflusher';
66
export { getCurrentHub, getHubFromCarrier, getMainCarrier, Hub, makeMain, setHubOnCarrier } from './hub';
77
export {

packages/hub/src/scope.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
RequestSession,
1414
Scope as ScopeInterface,
1515
ScopeContext,
16+
Session,
1617
Severity,
1718
SeverityLevel,
1819
Span,
@@ -29,7 +30,7 @@ import {
2930
} from '@sentry/utils';
3031

3132
import { IS_DEBUG_BUILD } from './flags';
32-
import { Session } from './session';
33+
import { updateSession } from './session';
3334

3435
/**
3536
* Absolute maximum number of breadcrumbs added to an event.
@@ -136,7 +137,7 @@ export class Scope implements ScopeInterface {
136137
public setUser(user: User | null): this {
137138
this._user = user || {};
138139
if (this._session) {
139-
this._session.update({ user });
140+
updateSession(this._session, { user });
140141
}
141142
this._notifyScopeListeners();
142143
return this;

0 commit comments

Comments
 (0)