UNPKG

5.48 kBJavaScriptView Raw
1import { _optionalChain } from '@sentry/utils/esm/buildPolyfills';
2import { BaseClient, SDK_VERSION } from '@sentry/core';
3import { SessionFlusher } from '@sentry/hub';
4import { logger, resolvedSyncPromise } from '@sentry/utils';
5import * as os from 'os';
6import { TextEncoder } from 'util';
7import { eventFromUnknownInput, eventFromMessage } from './eventbuilder.js';
8
9/**
10 * The Sentry Node SDK Client.
11 *
12 * @see NodeClientOptions for documentation on configuration options.
13 * @see SentryClient for usage documentation.
14 */
15class NodeClient extends BaseClient {
16
17
18 /**
19 * Creates a new Node SDK instance.
20 * @param options Configuration options for this SDK.
21 */
22 constructor(options) {
23 options._metadata = options._metadata || {};
24 options._metadata.sdk = options._metadata.sdk || {
25 name: 'sentry.javascript.node',
26 packages: [
27 {
28 name: 'npm:@sentry/node',
29 version: SDK_VERSION,
30 },
31 ],
32 version: SDK_VERSION,
33 };
34
35 // Until node supports global TextEncoder in all versions we support, we are forced to pass it from util
36 options.transportOptions = {
37 textEncoder: new TextEncoder(),
38 ...options.transportOptions,
39 };
40
41 super(options);
42 }
43
44 /**
45 * @inheritDoc
46 */
47 captureException(exception, hint, scope) {
48 // Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only
49 // when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload
50 // sent to the Server only when the `requestHandler` middleware is used
51 if (this._options.autoSessionTracking && this._sessionFlusher && scope) {
52 var requestSession = scope.getRequestSession();
53
54 // Necessary checks to ensure this is code block is executed only within a request
55 // Should override the status only if `requestSession.status` is `Ok`, which is its initial stage
56 if (requestSession && requestSession.status === 'ok') {
57 requestSession.status = 'errored';
58 }
59 }
60
61 return super.captureException(exception, hint, scope);
62 }
63
64 /**
65 * @inheritDoc
66 */
67 captureEvent(event, hint, scope) {
68 // Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only
69 // when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload
70 // sent to the Server only when the `requestHandler` middleware is used
71 if (this._options.autoSessionTracking && this._sessionFlusher && scope) {
72 var eventType = event.type || 'exception';
73 var isException =
74 eventType === 'exception' && event.exception && event.exception.values && event.exception.values.length > 0;
75
76 // If the event is of type Exception, then a request session should be captured
77 if (isException) {
78 var requestSession = scope.getRequestSession();
79
80 // Ensure that this is happening within the bounds of a request, and make sure not to override
81 // Session Status if Errored / Crashed
82 if (requestSession && requestSession.status === 'ok') {
83 requestSession.status = 'errored';
84 }
85 }
86 }
87
88 return super.captureEvent(event, hint, scope);
89 }
90
91 /**
92 *
93 * @inheritdoc
94 */
95 close(timeout) {
96 _optionalChain([this, 'access', _ => _._sessionFlusher, 'optionalAccess', _2 => _2.close, 'call', _3 => _3()]);
97 return super.close(timeout);
98 }
99
100 /** Method that initialises an instance of SessionFlusher on Client */
101 initSessionFlusher() {
102 const { release, environment } = this._options;
103 if (!release) {
104 (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('Cannot initialise an instance of SessionFlusher if no release is provided!');
105 } else {
106 this._sessionFlusher = new SessionFlusher(this, {
107 release,
108 environment,
109 });
110 }
111 }
112
113 /**
114 * @inheritDoc
115 */
116 eventFromException(exception, hint) {
117 return resolvedSyncPromise(eventFromUnknownInput(this._options.stackParser, exception, hint));
118 }
119
120 /**
121 * @inheritDoc
122 */
123 eventFromMessage(
124 message,
125 level = 'info',
126 hint,
127 ) {
128 return resolvedSyncPromise(
129 eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace),
130 );
131 }
132
133 /**
134 * @inheritDoc
135 */
136 _prepareEvent(event, hint, scope) {
137 event.platform = event.platform || 'node';
138 event.contexts = {
139 ...event.contexts,
140 runtime: _optionalChain([event, 'access', _4 => _4.contexts, 'optionalAccess', _5 => _5.runtime]) || {
141 name: 'node',
142 version: global.process.version,
143 },
144 };
145 event.server_name =
146 event.server_name || this.getOptions().serverName || global.process.env.SENTRY_NAME || os.hostname();
147 return super._prepareEvent(event, hint, scope);
148 }
149
150 /**
151 * Method responsible for capturing/ending a request session by calling `incrementSessionStatusCount` to increment
152 * appropriate session aggregates bucket
153 */
154 _captureRequestSession() {
155 if (!this._sessionFlusher) {
156 (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('Discarded request mode session because autoSessionTracking option was disabled');
157 } else {
158 this._sessionFlusher.incrementSessionStatusCount();
159 }
160 }
161}
162
163export { NodeClient };
164//# sourceMappingURL=client.js.map