UNPKG

18.3 kBJavaScriptView Raw
1Object.defineProperty(exports, "__esModule", { value: true });
2var tslib_1 = require("tslib");
3/* eslint-disable max-lines */
4var types_1 = require("@sentry/types");
5var utils_1 = require("@sentry/utils");
6var scope_1 = require("./scope");
7var session_1 = require("./session");
8/**
9 * API compatibility version of this hub.
10 *
11 * WARNING: This number should only be increased when the global interface
12 * changes and new methods are introduced.
13 *
14 * @hidden
15 */
16exports.API_VERSION = 4;
17/**
18 * Default maximum number of breadcrumbs added to an event. Can be overwritten
19 * with {@link Options.maxBreadcrumbs}.
20 */
21var DEFAULT_BREADCRUMBS = 100;
22/**
23 * Absolute maximum number of breadcrumbs added to an event. The
24 * `maxBreadcrumbs` option cannot be higher than this value.
25 */
26var MAX_BREADCRUMBS = 100;
27/**
28 * @inheritDoc
29 */
30var Hub = /** @class */ (function () {
31 /**
32 * Creates a new instance of the hub, will push one {@link Layer} into the
33 * internal stack on creation.
34 *
35 * @param client bound to the hub.
36 * @param scope bound to the hub.
37 * @param version number, higher number means higher priority.
38 */
39 function Hub(client, scope, _version) {
40 if (scope === void 0) { scope = new scope_1.Scope(); }
41 if (_version === void 0) { _version = exports.API_VERSION; }
42 this._version = _version;
43 /** Is a {@link Layer}[] containing the client and scope */
44 this._stack = [{}];
45 this.getStackTop().scope = scope;
46 this.bindClient(client);
47 }
48 /**
49 * @inheritDoc
50 */
51 Hub.prototype.isOlderThan = function (version) {
52 return this._version < version;
53 };
54 /**
55 * @inheritDoc
56 */
57 Hub.prototype.bindClient = function (client) {
58 var top = this.getStackTop();
59 top.client = client;
60 if (client && client.setupIntegrations) {
61 client.setupIntegrations();
62 }
63 };
64 /**
65 * @inheritDoc
66 */
67 Hub.prototype.pushScope = function () {
68 // We want to clone the content of prev scope
69 var scope = scope_1.Scope.clone(this.getScope());
70 this.getStack().push({
71 client: this.getClient(),
72 scope: scope,
73 });
74 return scope;
75 };
76 /**
77 * @inheritDoc
78 */
79 Hub.prototype.popScope = function () {
80 if (this.getStack().length <= 1)
81 return false;
82 return !!this.getStack().pop();
83 };
84 /**
85 * @inheritDoc
86 */
87 Hub.prototype.withScope = function (callback) {
88 var scope = this.pushScope();
89 try {
90 callback(scope);
91 }
92 finally {
93 this.popScope();
94 }
95 };
96 /**
97 * @inheritDoc
98 */
99 Hub.prototype.getClient = function () {
100 return this.getStackTop().client;
101 };
102 /** Returns the scope of the top stack. */
103 Hub.prototype.getScope = function () {
104 return this.getStackTop().scope;
105 };
106 /** Returns the scope stack for domains or the process. */
107 Hub.prototype.getStack = function () {
108 return this._stack;
109 };
110 /** Returns the topmost scope layer in the order domain > local > process. */
111 Hub.prototype.getStackTop = function () {
112 return this._stack[this._stack.length - 1];
113 };
114 /**
115 * @inheritDoc
116 */
117 // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
118 Hub.prototype.captureException = function (exception, hint) {
119 var eventId = (this._lastEventId = utils_1.uuid4());
120 var finalHint = hint;
121 // If there's no explicit hint provided, mimick the same thing that would happen
122 // in the minimal itself to create a consistent behavior.
123 // We don't do this in the client, as it's the lowest level API, and doing this,
124 // would prevent user from having full control over direct calls.
125 if (!hint) {
126 var syntheticException = void 0;
127 try {
128 throw new Error('Sentry syntheticException');
129 }
130 catch (exception) {
131 syntheticException = exception;
132 }
133 finalHint = {
134 originalException: exception,
135 syntheticException: syntheticException,
136 };
137 }
138 this._invokeClient('captureException', exception, tslib_1.__assign(tslib_1.__assign({}, finalHint), { event_id: eventId }));
139 return eventId;
140 };
141 /**
142 * @inheritDoc
143 */
144 Hub.prototype.captureMessage = function (message, level, hint) {
145 var eventId = (this._lastEventId = utils_1.uuid4());
146 var finalHint = hint;
147 // If there's no explicit hint provided, mimick the same thing that would happen
148 // in the minimal itself to create a consistent behavior.
149 // We don't do this in the client, as it's the lowest level API, and doing this,
150 // would prevent user from having full control over direct calls.
151 if (!hint) {
152 var syntheticException = void 0;
153 try {
154 throw new Error(message);
155 }
156 catch (exception) {
157 syntheticException = exception;
158 }
159 finalHint = {
160 originalException: message,
161 syntheticException: syntheticException,
162 };
163 }
164 this._invokeClient('captureMessage', message, level, tslib_1.__assign(tslib_1.__assign({}, finalHint), { event_id: eventId }));
165 return eventId;
166 };
167 /**
168 * @inheritDoc
169 */
170 Hub.prototype.captureEvent = function (event, hint) {
171 var eventId = (this._lastEventId = utils_1.uuid4());
172 this._invokeClient('captureEvent', event, tslib_1.__assign(tslib_1.__assign({}, hint), { event_id: eventId }));
173 return eventId;
174 };
175 /**
176 * @inheritDoc
177 */
178 Hub.prototype.lastEventId = function () {
179 return this._lastEventId;
180 };
181 /**
182 * @inheritDoc
183 */
184 Hub.prototype.addBreadcrumb = function (breadcrumb, hint) {
185 var _a = this.getStackTop(), scope = _a.scope, client = _a.client;
186 if (!scope || !client)
187 return;
188 // eslint-disable-next-line @typescript-eslint/unbound-method
189 var _b = (client.getOptions && client.getOptions()) || {}, _c = _b.beforeBreadcrumb, beforeBreadcrumb = _c === void 0 ? null : _c, _d = _b.maxBreadcrumbs, maxBreadcrumbs = _d === void 0 ? DEFAULT_BREADCRUMBS : _d;
190 if (maxBreadcrumbs <= 0)
191 return;
192 var timestamp = utils_1.dateTimestampInSeconds();
193 var mergedBreadcrumb = tslib_1.__assign({ timestamp: timestamp }, breadcrumb);
194 var finalBreadcrumb = beforeBreadcrumb
195 ? utils_1.consoleSandbox(function () { return beforeBreadcrumb(mergedBreadcrumb, hint); })
196 : mergedBreadcrumb;
197 if (finalBreadcrumb === null)
198 return;
199 scope.addBreadcrumb(finalBreadcrumb, Math.min(maxBreadcrumbs, MAX_BREADCRUMBS));
200 };
201 /**
202 * @inheritDoc
203 */
204 Hub.prototype.setUser = function (user) {
205 var scope = this.getScope();
206 if (scope)
207 scope.setUser(user);
208 };
209 /**
210 * @inheritDoc
211 */
212 Hub.prototype.setTags = function (tags) {
213 var scope = this.getScope();
214 if (scope)
215 scope.setTags(tags);
216 };
217 /**
218 * @inheritDoc
219 */
220 Hub.prototype.setExtras = function (extras) {
221 var scope = this.getScope();
222 if (scope)
223 scope.setExtras(extras);
224 };
225 /**
226 * @inheritDoc
227 */
228 Hub.prototype.setTag = function (key, value) {
229 var scope = this.getScope();
230 if (scope)
231 scope.setTag(key, value);
232 };
233 /**
234 * @inheritDoc
235 */
236 Hub.prototype.setExtra = function (key, extra) {
237 var scope = this.getScope();
238 if (scope)
239 scope.setExtra(key, extra);
240 };
241 /**
242 * @inheritDoc
243 */
244 // eslint-disable-next-line @typescript-eslint/no-explicit-any
245 Hub.prototype.setContext = function (name, context) {
246 var scope = this.getScope();
247 if (scope)
248 scope.setContext(name, context);
249 };
250 /**
251 * @inheritDoc
252 */
253 Hub.prototype.configureScope = function (callback) {
254 var _a = this.getStackTop(), scope = _a.scope, client = _a.client;
255 if (scope && client) {
256 callback(scope);
257 }
258 };
259 /**
260 * @inheritDoc
261 */
262 Hub.prototype.run = function (callback) {
263 var oldHub = makeMain(this);
264 try {
265 callback(this);
266 }
267 finally {
268 makeMain(oldHub);
269 }
270 };
271 /**
272 * @inheritDoc
273 */
274 Hub.prototype.getIntegration = function (integration) {
275 var client = this.getClient();
276 if (!client)
277 return null;
278 try {
279 return client.getIntegration(integration);
280 }
281 catch (_oO) {
282 utils_1.logger.warn("Cannot retrieve integration " + integration.id + " from the current Hub");
283 return null;
284 }
285 };
286 /**
287 * @inheritDoc
288 */
289 Hub.prototype.startSpan = function (context) {
290 return this._callExtensionMethod('startSpan', context);
291 };
292 /**
293 * @inheritDoc
294 */
295 Hub.prototype.startTransaction = function (context, customSamplingContext) {
296 return this._callExtensionMethod('startTransaction', context, customSamplingContext);
297 };
298 /**
299 * @inheritDoc
300 */
301 Hub.prototype.traceHeaders = function () {
302 return this._callExtensionMethod('traceHeaders');
303 };
304 /**
305 * @inheritDoc
306 */
307 Hub.prototype.captureSession = function (endSession) {
308 if (endSession === void 0) { endSession = false; }
309 // both send the update and pull the session from the scope
310 if (endSession) {
311 return this.endSession();
312 }
313 // only send the update
314 this._sendSessionUpdate();
315 };
316 /**
317 * @inheritDoc
318 */
319 Hub.prototype.endSession = function () {
320 var _a, _b, _c, _d, _e;
321 (_c = (_b = (_a = this.getStackTop()) === null || _a === void 0 ? void 0 : _a.scope) === null || _b === void 0 ? void 0 : _b.getSession()) === null || _c === void 0 ? void 0 : _c.close();
322 this._sendSessionUpdate();
323 // the session is over; take it off of the scope
324 (_e = (_d = this.getStackTop()) === null || _d === void 0 ? void 0 : _d.scope) === null || _e === void 0 ? void 0 : _e.setSession();
325 };
326 /**
327 * @inheritDoc
328 */
329 Hub.prototype.startSession = function (context) {
330 var _a = this.getStackTop(), scope = _a.scope, client = _a.client;
331 var _b = (client && client.getOptions()) || {}, release = _b.release, environment = _b.environment;
332 var session = new session_1.Session(tslib_1.__assign(tslib_1.__assign({ release: release,
333 environment: environment }, (scope && { user: scope.getUser() })), context));
334 if (scope) {
335 // End existing session if there's one
336 var currentSession = scope.getSession && scope.getSession();
337 if (currentSession && currentSession.status === types_1.SessionStatus.Ok) {
338 currentSession.update({ status: types_1.SessionStatus.Exited });
339 }
340 this.endSession();
341 // Afterwards we set the new session on the scope
342 scope.setSession(session);
343 }
344 return session;
345 };
346 /**
347 * Sends the current Session on the scope
348 */
349 Hub.prototype._sendSessionUpdate = function () {
350 var _a = this.getStackTop(), scope = _a.scope, client = _a.client;
351 if (!scope)
352 return;
353 var session = scope.getSession && scope.getSession();
354 if (session) {
355 if (client && client.captureSession) {
356 client.captureSession(session);
357 }
358 }
359 };
360 /**
361 * Internal helper function to call a method on the top client if it exists.
362 *
363 * @param method The method to call on the client.
364 * @param args Arguments to pass to the client function.
365 */
366 // eslint-disable-next-line @typescript-eslint/no-explicit-any
367 Hub.prototype._invokeClient = function (method) {
368 var _a;
369 var args = [];
370 for (var _i = 1; _i < arguments.length; _i++) {
371 args[_i - 1] = arguments[_i];
372 }
373 var _b = this.getStackTop(), scope = _b.scope, client = _b.client;
374 if (client && client[method]) {
375 // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
376 (_a = client)[method].apply(_a, tslib_1.__spread(args, [scope]));
377 }
378 };
379 /**
380 * Calls global extension method and binding current instance to the function call
381 */
382 // @ts-ignore Function lacks ending return statement and return type does not include 'undefined'. ts(2366)
383 // eslint-disable-next-line @typescript-eslint/no-explicit-any
384 Hub.prototype._callExtensionMethod = function (method) {
385 var args = [];
386 for (var _i = 1; _i < arguments.length; _i++) {
387 args[_i - 1] = arguments[_i];
388 }
389 var carrier = getMainCarrier();
390 var sentry = carrier.__SENTRY__;
391 if (sentry && sentry.extensions && typeof sentry.extensions[method] === 'function') {
392 return sentry.extensions[method].apply(this, args);
393 }
394 utils_1.logger.warn("Extension method " + method + " couldn't be found, doing nothing.");
395 };
396 return Hub;
397}());
398exports.Hub = Hub;
399/**
400 * Returns the global shim registry.
401 *
402 * FIXME: This function is problematic, because despite always returning a valid Carrier,
403 * it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check
404 * at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.
405 **/
406function getMainCarrier() {
407 var carrier = utils_1.getGlobalObject();
408 carrier.__SENTRY__ = carrier.__SENTRY__ || {
409 extensions: {},
410 hub: undefined,
411 };
412 return carrier;
413}
414exports.getMainCarrier = getMainCarrier;
415/**
416 * Replaces the current main hub with the passed one on the global object
417 *
418 * @returns The old replaced hub
419 */
420function makeMain(hub) {
421 var registry = getMainCarrier();
422 var oldHub = getHubFromCarrier(registry);
423 setHubOnCarrier(registry, hub);
424 return oldHub;
425}
426exports.makeMain = makeMain;
427/**
428 * Returns the default hub instance.
429 *
430 * If a hub is already registered in the global carrier but this module
431 * contains a more recent version, it replaces the registered version.
432 * Otherwise, the currently registered hub will be returned.
433 */
434function getCurrentHub() {
435 // Get main carrier (global for every environment)
436 var registry = getMainCarrier();
437 // If there's no hub, or its an old API, assign a new one
438 if (!hasHubOnCarrier(registry) || getHubFromCarrier(registry).isOlderThan(exports.API_VERSION)) {
439 setHubOnCarrier(registry, new Hub());
440 }
441 // Prefer domains over global if they are there (applicable only to Node environment)
442 if (utils_1.isNodeEnv()) {
443 return getHubFromActiveDomain(registry);
444 }
445 // Return hub that lives on a global object
446 return getHubFromCarrier(registry);
447}
448exports.getCurrentHub = getCurrentHub;
449/**
450 * Returns the active domain, if one exists
451 * @deprecated No longer used; remove in v7
452 * @returns The domain, or undefined if there is no active domain
453 */
454// eslint-disable-next-line deprecation/deprecation
455function getActiveDomain() {
456 utils_1.logger.warn('Function `getActiveDomain` is deprecated and will be removed in a future version.');
457 var sentry = getMainCarrier().__SENTRY__;
458 return sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active;
459}
460exports.getActiveDomain = getActiveDomain;
461/**
462 * Try to read the hub from an active domain, and fallback to the registry if one doesn't exist
463 * @returns discovered hub
464 */
465function getHubFromActiveDomain(registry) {
466 var _a, _b, _c;
467 try {
468 var activeDomain = (_c = (_b = (_a = getMainCarrier().__SENTRY__) === null || _a === void 0 ? void 0 : _a.extensions) === null || _b === void 0 ? void 0 : _b.domain) === null || _c === void 0 ? void 0 : _c.active;
469 // If there's no active domain, just return global hub
470 if (!activeDomain) {
471 return getHubFromCarrier(registry);
472 }
473 // If there's no hub on current domain, or it's an old API, assign a new one
474 if (!hasHubOnCarrier(activeDomain) || getHubFromCarrier(activeDomain).isOlderThan(exports.API_VERSION)) {
475 var registryHubTopStack = getHubFromCarrier(registry).getStackTop();
476 setHubOnCarrier(activeDomain, new Hub(registryHubTopStack.client, scope_1.Scope.clone(registryHubTopStack.scope)));
477 }
478 // Return hub that lives on a domain
479 return getHubFromCarrier(activeDomain);
480 }
481 catch (_Oo) {
482 // Return hub that lives on a global object
483 return getHubFromCarrier(registry);
484 }
485}
486/**
487 * This will tell whether a carrier has a hub on it or not
488 * @param carrier object
489 */
490function hasHubOnCarrier(carrier) {
491 return !!(carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub);
492}
493/**
494 * This will create a new {@link Hub} and add to the passed object on
495 * __SENTRY__.hub.
496 * @param carrier object
497 * @hidden
498 */
499function getHubFromCarrier(carrier) {
500 if (carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub)
501 return carrier.__SENTRY__.hub;
502 carrier.__SENTRY__ = carrier.__SENTRY__ || {};
503 carrier.__SENTRY__.hub = new Hub();
504 return carrier.__SENTRY__.hub;
505}
506exports.getHubFromCarrier = getHubFromCarrier;
507/**
508 * This will set passed {@link Hub} on the passed object's __SENTRY__.hub attribute
509 * @param carrier object
510 * @param hub Hub
511 * @returns A boolean indicating success or failure
512 */
513function setHubOnCarrier(carrier, hub) {
514 if (!carrier)
515 return false;
516 carrier.__SENTRY__ = carrier.__SENTRY__ || {};
517 carrier.__SENTRY__.hub = hub;
518 return true;
519}
520exports.setHubOnCarrier = setHubOnCarrier;
521//# sourceMappingURL=hub.js.map
\No newline at end of file