/
client.ts
130 lines (115 loc) · 4.67 KB
/
client.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { BaseClient, Scope, SDK_VERSION } from '@sentry/core';
import { SessionFlusher } from '@sentry/hub';
import { Event, EventHint, RequestSessionStatus } from '@sentry/types';
import { logger } from '@sentry/utils';
import { NodeBackend } from './backend';
import { NodeOptions } from './types';
/**
* The Sentry Node SDK Client.
*
* @see NodeOptions for documentation on configuration options.
* @see SentryClient for usage documentation.
*/
export class NodeClient extends BaseClient<NodeBackend, NodeOptions> {
protected _sessionFlusher: SessionFlusher | undefined;
/**
* Creates a new Node SDK instance.
* @param options Configuration options for this SDK.
*/
public constructor(options: NodeOptions) {
options._metadata = options._metadata || {};
options._metadata.sdk = options._metadata.sdk || {
name: 'sentry.javascript.node',
packages: [
{
name: 'npm:@sentry/node',
version: SDK_VERSION,
},
],
version: SDK_VERSION,
};
super(NodeBackend, options);
}
/**
* @inheritDoc
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
public captureException(exception: any, hint?: EventHint, scope?: Scope): string | undefined {
// Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only
// when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload
// sent to the Server only when the `requestHandler` middleware is used
if (this._options.autoSessionTracking && this._sessionFlusher && scope) {
const requestSession = scope.getRequestSession();
// Necessary checks to ensure this is code block is executed only within a request
// Should override the status only if `requestSession.status` is `Ok`, which is its initial stage
if (requestSession && requestSession.status === RequestSessionStatus.Ok) {
requestSession.status = RequestSessionStatus.Errored;
}
}
return super.captureException(exception, hint, scope);
}
/**
* @inheritDoc
*/
public captureEvent(event: Event, hint?: EventHint, scope?: Scope): string | undefined {
// Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only
// when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload
// sent to the Server only when the `requestHandler` middleware is used
if (this._options.autoSessionTracking && this._sessionFlusher && scope) {
const eventType = event.type || 'exception';
const isException =
eventType === 'exception' && event.exception && event.exception.values && event.exception.values.length > 0;
// If the event is of type Exception, then a request session should be captured
if (isException) {
const requestSession = scope.getRequestSession();
// Ensure that this is happening within the bounds of a request, and make sure not to override
// Session Status if Errored / Crashed
if (requestSession && requestSession.status === RequestSessionStatus.Ok) {
requestSession.status = RequestSessionStatus.Errored;
}
}
}
return super.captureEvent(event, hint, scope);
}
/**
*
* @inheritdoc
*/
public close(timeout?: number): PromiseLike<boolean> {
this._sessionFlusher?.close();
return super.close(timeout);
}
/** Method that initialises an instance of SessionFlusher on Client */
public initSessionFlusher(): void {
const { release, environment } = this._options;
if (!release) {
logger.warn('Cannot initialise an instance of SessionFlusher if no release is provided!');
} else {
this._sessionFlusher = new SessionFlusher(this.getTransport(), {
release,
environment,
});
}
}
/**
* @inheritDoc
*/
protected _prepareEvent(event: Event, scope?: Scope, hint?: EventHint): PromiseLike<Event | null> {
event.platform = event.platform || 'node';
if (this.getOptions().serverName) {
event.server_name = this.getOptions().serverName;
}
return super._prepareEvent(event, scope, hint);
}
/**
* Method responsible for capturing/ending a request session by calling `incrementSessionStatusCount` to increment
* appropriate session aggregates bucket
*/
protected _captureRequestSession(): void {
if (!this._sessionFlusher) {
logger.warn('Discarded request mode session because autoSessionTracking option was disabled');
} else {
this._sessionFlusher.incrementSessionStatusCount();
}
}
}