hub.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. Object.defineProperty(exports, '__esModule', { value: true });
  2. const utils = require('@sentry/utils');
  3. const constants = require('./constants.js');
  4. const debugBuild = require('./debug-build.js');
  5. const scope = require('./scope.js');
  6. const session = require('./session.js');
  7. const version = require('./version.js');
  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. */
  16. const API_VERSION = parseFloat(version.SDK_VERSION);
  17. /**
  18. * Default maximum number of breadcrumbs added to an event. Can be overwritten
  19. * with {@link Options.maxBreadcrumbs}.
  20. */
  21. const DEFAULT_BREADCRUMBS = 100;
  22. /**
  23. * @inheritDoc
  24. */
  25. class Hub {
  26. /** Is a {@link Layer}[] containing the client and scope */
  27. /** Contains the last event id of a captured event. */
  28. /**
  29. * Creates a new instance of the hub, will push one {@link Layer} into the
  30. * internal stack on creation.
  31. *
  32. * @param client bound to the hub.
  33. * @param scope bound to the hub.
  34. * @param version number, higher number means higher priority.
  35. *
  36. * @deprecated Instantiation of Hub objects is deprecated and the constructor will be removed in version 8 of the SDK.
  37. *
  38. * If you are currently using the Hub for multi-client use like so:
  39. *
  40. * ```
  41. * // OLD
  42. * const hub = new Hub();
  43. * hub.bindClient(client);
  44. * makeMain(hub)
  45. * ```
  46. *
  47. * instead initialize the client as follows:
  48. *
  49. * ```
  50. * // NEW
  51. * Sentry.withIsolationScope(() => {
  52. * Sentry.setCurrentClient(client);
  53. * client.init();
  54. * });
  55. * ```
  56. *
  57. * If you are using the Hub to capture events like so:
  58. *
  59. * ```
  60. * // OLD
  61. * const client = new Client();
  62. * const hub = new Hub(client);
  63. * hub.captureException()
  64. * ```
  65. *
  66. * instead capture isolated events as follows:
  67. *
  68. * ```
  69. * // NEW
  70. * const client = new Client();
  71. * const scope = new Scope();
  72. * scope.setClient(client);
  73. * scope.captureException();
  74. * ```
  75. */
  76. constructor(
  77. client,
  78. scope$1,
  79. isolationScope,
  80. _version = API_VERSION,
  81. ) {this._version = _version;
  82. let assignedScope;
  83. if (!scope$1) {
  84. assignedScope = new scope.Scope();
  85. assignedScope.setClient(client);
  86. } else {
  87. assignedScope = scope$1;
  88. }
  89. let assignedIsolationScope;
  90. if (!isolationScope) {
  91. assignedIsolationScope = new scope.Scope();
  92. assignedIsolationScope.setClient(client);
  93. } else {
  94. assignedIsolationScope = isolationScope;
  95. }
  96. this._stack = [{ scope: assignedScope }];
  97. if (client) {
  98. // eslint-disable-next-line deprecation/deprecation
  99. this.bindClient(client);
  100. }
  101. this._isolationScope = assignedIsolationScope;
  102. }
  103. /**
  104. * Checks if this hub's version is older than the given version.
  105. *
  106. * @param version A version number to compare to.
  107. * @return True if the given version is newer; otherwise false.
  108. *
  109. * @deprecated This will be removed in v8.
  110. */
  111. isOlderThan(version) {
  112. return this._version < version;
  113. }
  114. /**
  115. * This binds the given client to the current scope.
  116. * @param client An SDK client (client) instance.
  117. *
  118. * @deprecated Use `initAndBind()` directly, or `setCurrentClient()` and/or `client.init()` instead.
  119. */
  120. bindClient(client) {
  121. // eslint-disable-next-line deprecation/deprecation
  122. const top = this.getStackTop();
  123. top.client = client;
  124. top.scope.setClient(client);
  125. // eslint-disable-next-line deprecation/deprecation
  126. if (client && client.setupIntegrations) {
  127. // eslint-disable-next-line deprecation/deprecation
  128. client.setupIntegrations();
  129. }
  130. }
  131. /**
  132. * @inheritDoc
  133. *
  134. * @deprecated Use `withScope` instead.
  135. */
  136. pushScope() {
  137. // We want to clone the content of prev scope
  138. // eslint-disable-next-line deprecation/deprecation
  139. const scope = this.getScope().clone();
  140. // eslint-disable-next-line deprecation/deprecation
  141. this.getStack().push({
  142. // eslint-disable-next-line deprecation/deprecation
  143. client: this.getClient(),
  144. scope,
  145. });
  146. return scope;
  147. }
  148. /**
  149. * @inheritDoc
  150. *
  151. * @deprecated Use `withScope` instead.
  152. */
  153. popScope() {
  154. // eslint-disable-next-line deprecation/deprecation
  155. if (this.getStack().length <= 1) return false;
  156. // eslint-disable-next-line deprecation/deprecation
  157. return !!this.getStack().pop();
  158. }
  159. /**
  160. * @inheritDoc
  161. *
  162. * @deprecated Use `Sentry.withScope()` instead.
  163. */
  164. withScope(callback) {
  165. // eslint-disable-next-line deprecation/deprecation
  166. const scope = this.pushScope();
  167. let maybePromiseResult;
  168. try {
  169. maybePromiseResult = callback(scope);
  170. } catch (e) {
  171. // eslint-disable-next-line deprecation/deprecation
  172. this.popScope();
  173. throw e;
  174. }
  175. if (utils.isThenable(maybePromiseResult)) {
  176. // @ts-expect-error - isThenable returns the wrong type
  177. return maybePromiseResult.then(
  178. res => {
  179. // eslint-disable-next-line deprecation/deprecation
  180. this.popScope();
  181. return res;
  182. },
  183. e => {
  184. // eslint-disable-next-line deprecation/deprecation
  185. this.popScope();
  186. throw e;
  187. },
  188. );
  189. }
  190. // eslint-disable-next-line deprecation/deprecation
  191. this.popScope();
  192. return maybePromiseResult;
  193. }
  194. /**
  195. * @inheritDoc
  196. *
  197. * @deprecated Use `Sentry.getClient()` instead.
  198. */
  199. getClient() {
  200. // eslint-disable-next-line deprecation/deprecation
  201. return this.getStackTop().client ;
  202. }
  203. /**
  204. * Returns the scope of the top stack.
  205. *
  206. * @deprecated Use `Sentry.getCurrentScope()` instead.
  207. */
  208. getScope() {
  209. // eslint-disable-next-line deprecation/deprecation
  210. return this.getStackTop().scope;
  211. }
  212. /**
  213. * @deprecated Use `Sentry.getIsolationScope()` instead.
  214. */
  215. getIsolationScope() {
  216. return this._isolationScope;
  217. }
  218. /**
  219. * Returns the scope stack for domains or the process.
  220. * @deprecated This will be removed in v8.
  221. */
  222. getStack() {
  223. return this._stack;
  224. }
  225. /**
  226. * Returns the topmost scope layer in the order domain > local > process.
  227. * @deprecated This will be removed in v8.
  228. */
  229. getStackTop() {
  230. return this._stack[this._stack.length - 1];
  231. }
  232. /**
  233. * @inheritDoc
  234. *
  235. * @deprecated Use `Sentry.captureException()` instead.
  236. */
  237. captureException(exception, hint) {
  238. const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : utils.uuid4());
  239. const syntheticException = new Error('Sentry syntheticException');
  240. // eslint-disable-next-line deprecation/deprecation
  241. this.getScope().captureException(exception, {
  242. originalException: exception,
  243. syntheticException,
  244. ...hint,
  245. event_id: eventId,
  246. });
  247. return eventId;
  248. }
  249. /**
  250. * @inheritDoc
  251. *
  252. * @deprecated Use `Sentry.captureMessage()` instead.
  253. */
  254. captureMessage(
  255. message,
  256. // eslint-disable-next-line deprecation/deprecation
  257. level,
  258. hint,
  259. ) {
  260. const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : utils.uuid4());
  261. const syntheticException = new Error(message);
  262. // eslint-disable-next-line deprecation/deprecation
  263. this.getScope().captureMessage(message, level, {
  264. originalException: message,
  265. syntheticException,
  266. ...hint,
  267. event_id: eventId,
  268. });
  269. return eventId;
  270. }
  271. /**
  272. * @inheritDoc
  273. *
  274. * @deprecated Use `Sentry.captureEvent()` instead.
  275. */
  276. captureEvent(event, hint) {
  277. const eventId = hint && hint.event_id ? hint.event_id : utils.uuid4();
  278. if (!event.type) {
  279. this._lastEventId = eventId;
  280. }
  281. // eslint-disable-next-line deprecation/deprecation
  282. this.getScope().captureEvent(event, { ...hint, event_id: eventId });
  283. return eventId;
  284. }
  285. /**
  286. * @inheritDoc
  287. *
  288. * @deprecated This will be removed in v8.
  289. */
  290. lastEventId() {
  291. return this._lastEventId;
  292. }
  293. /**
  294. * @inheritDoc
  295. *
  296. * @deprecated Use `Sentry.addBreadcrumb()` instead.
  297. */
  298. addBreadcrumb(breadcrumb, hint) {
  299. // eslint-disable-next-line deprecation/deprecation
  300. const { scope, client } = this.getStackTop();
  301. if (!client) return;
  302. const { beforeBreadcrumb = null, maxBreadcrumbs = DEFAULT_BREADCRUMBS } =
  303. (client.getOptions && client.getOptions()) || {};
  304. if (maxBreadcrumbs <= 0) return;
  305. const timestamp = utils.dateTimestampInSeconds();
  306. const mergedBreadcrumb = { timestamp, ...breadcrumb };
  307. const finalBreadcrumb = beforeBreadcrumb
  308. ? (utils.consoleSandbox(() => beforeBreadcrumb(mergedBreadcrumb, hint)) )
  309. : mergedBreadcrumb;
  310. if (finalBreadcrumb === null) return;
  311. if (client.emit) {
  312. client.emit('beforeAddBreadcrumb', finalBreadcrumb, hint);
  313. }
  314. // TODO(v8): I know this comment doesn't make much sense because the hub will be deprecated but I still wanted to
  315. // write it down. In theory, we would have to add the breadcrumbs to the isolation scope here, however, that would
  316. // duplicate all of the breadcrumbs. There was the possibility of adding breadcrumbs to both, the isolation scope
  317. // and the normal scope, and deduplicating it down the line in the event processing pipeline. However, that would
  318. // have been very fragile, because the breadcrumb objects would have needed to keep their identity all throughout
  319. // the event processing pipeline.
  320. // In the new implementation, the top level `Sentry.addBreadcrumb()` should ONLY write to the isolation scope.
  321. scope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs);
  322. }
  323. /**
  324. * @inheritDoc
  325. * @deprecated Use `Sentry.setUser()` instead.
  326. */
  327. setUser(user) {
  328. // TODO(v8): The top level `Sentry.setUser()` function should write ONLY to the isolation scope.
  329. // eslint-disable-next-line deprecation/deprecation
  330. this.getScope().setUser(user);
  331. // eslint-disable-next-line deprecation/deprecation
  332. this.getIsolationScope().setUser(user);
  333. }
  334. /**
  335. * @inheritDoc
  336. * @deprecated Use `Sentry.setTags()` instead.
  337. */
  338. setTags(tags) {
  339. // TODO(v8): The top level `Sentry.setTags()` function should write ONLY to the isolation scope.
  340. // eslint-disable-next-line deprecation/deprecation
  341. this.getScope().setTags(tags);
  342. // eslint-disable-next-line deprecation/deprecation
  343. this.getIsolationScope().setTags(tags);
  344. }
  345. /**
  346. * @inheritDoc
  347. * @deprecated Use `Sentry.setExtras()` instead.
  348. */
  349. setExtras(extras) {
  350. // TODO(v8): The top level `Sentry.setExtras()` function should write ONLY to the isolation scope.
  351. // eslint-disable-next-line deprecation/deprecation
  352. this.getScope().setExtras(extras);
  353. // eslint-disable-next-line deprecation/deprecation
  354. this.getIsolationScope().setExtras(extras);
  355. }
  356. /**
  357. * @inheritDoc
  358. * @deprecated Use `Sentry.setTag()` instead.
  359. */
  360. setTag(key, value) {
  361. // TODO(v8): The top level `Sentry.setTag()` function should write ONLY to the isolation scope.
  362. // eslint-disable-next-line deprecation/deprecation
  363. this.getScope().setTag(key, value);
  364. // eslint-disable-next-line deprecation/deprecation
  365. this.getIsolationScope().setTag(key, value);
  366. }
  367. /**
  368. * @inheritDoc
  369. * @deprecated Use `Sentry.setExtra()` instead.
  370. */
  371. setExtra(key, extra) {
  372. // TODO(v8): The top level `Sentry.setExtra()` function should write ONLY to the isolation scope.
  373. // eslint-disable-next-line deprecation/deprecation
  374. this.getScope().setExtra(key, extra);
  375. // eslint-disable-next-line deprecation/deprecation
  376. this.getIsolationScope().setExtra(key, extra);
  377. }
  378. /**
  379. * @inheritDoc
  380. * @deprecated Use `Sentry.setContext()` instead.
  381. */
  382. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  383. setContext(name, context) {
  384. // TODO(v8): The top level `Sentry.setContext()` function should write ONLY to the isolation scope.
  385. // eslint-disable-next-line deprecation/deprecation
  386. this.getScope().setContext(name, context);
  387. // eslint-disable-next-line deprecation/deprecation
  388. this.getIsolationScope().setContext(name, context);
  389. }
  390. /**
  391. * @inheritDoc
  392. *
  393. * @deprecated Use `getScope()` directly.
  394. */
  395. configureScope(callback) {
  396. // eslint-disable-next-line deprecation/deprecation
  397. const { scope, client } = this.getStackTop();
  398. if (client) {
  399. callback(scope);
  400. }
  401. }
  402. /**
  403. * @inheritDoc
  404. */
  405. run(callback) {
  406. // eslint-disable-next-line deprecation/deprecation
  407. const oldHub = makeMain(this);
  408. try {
  409. callback(this);
  410. } finally {
  411. // eslint-disable-next-line deprecation/deprecation
  412. makeMain(oldHub);
  413. }
  414. }
  415. /**
  416. * @inheritDoc
  417. * @deprecated Use `Sentry.getClient().getIntegrationByName()` instead.
  418. */
  419. getIntegration(integration) {
  420. // eslint-disable-next-line deprecation/deprecation
  421. const client = this.getClient();
  422. if (!client) return null;
  423. try {
  424. // eslint-disable-next-line deprecation/deprecation
  425. return client.getIntegration(integration);
  426. } catch (_oO) {
  427. debugBuild.DEBUG_BUILD && utils.logger.warn(`Cannot retrieve integration ${integration.id} from the current Hub`);
  428. return null;
  429. }
  430. }
  431. /**
  432. * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation.
  433. *
  434. * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a
  435. * new child span within the transaction or any span, call the respective `.startChild()` method.
  436. *
  437. * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded.
  438. *
  439. * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its
  440. * finished child spans will be sent to Sentry.
  441. *
  442. * @param context Properties of the new `Transaction`.
  443. * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent
  444. * default values). See {@link Options.tracesSampler}.
  445. *
  446. * @returns The transaction which was just started
  447. *
  448. * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead.
  449. */
  450. startTransaction(context, customSamplingContext) {
  451. const result = this._callExtensionMethod('startTransaction', context, customSamplingContext);
  452. if (debugBuild.DEBUG_BUILD && !result) {
  453. // eslint-disable-next-line deprecation/deprecation
  454. const client = this.getClient();
  455. if (!client) {
  456. utils.logger.warn(
  457. "Tracing extension 'startTransaction' is missing. You should 'init' the SDK before calling 'startTransaction'",
  458. );
  459. } else {
  460. utils.logger.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init':
  461. Sentry.addTracingExtensions();
  462. Sentry.init({...});
  463. `);
  464. }
  465. }
  466. return result;
  467. }
  468. /**
  469. * @inheritDoc
  470. * @deprecated Use `spanToTraceHeader()` instead.
  471. */
  472. traceHeaders() {
  473. return this._callExtensionMethod('traceHeaders');
  474. }
  475. /**
  476. * @inheritDoc
  477. *
  478. * @deprecated Use top level `captureSession` instead.
  479. */
  480. captureSession(endSession = false) {
  481. // both send the update and pull the session from the scope
  482. if (endSession) {
  483. // eslint-disable-next-line deprecation/deprecation
  484. return this.endSession();
  485. }
  486. // only send the update
  487. this._sendSessionUpdate();
  488. }
  489. /**
  490. * @inheritDoc
  491. * @deprecated Use top level `endSession` instead.
  492. */
  493. endSession() {
  494. // eslint-disable-next-line deprecation/deprecation
  495. const layer = this.getStackTop();
  496. const scope = layer.scope;
  497. const session$1 = scope.getSession();
  498. if (session$1) {
  499. session.closeSession(session$1);
  500. }
  501. this._sendSessionUpdate();
  502. // the session is over; take it off of the scope
  503. scope.setSession();
  504. }
  505. /**
  506. * @inheritDoc
  507. * @deprecated Use top level `startSession` instead.
  508. */
  509. startSession(context) {
  510. // eslint-disable-next-line deprecation/deprecation
  511. const { scope, client } = this.getStackTop();
  512. const { release, environment = constants.DEFAULT_ENVIRONMENT } = (client && client.getOptions()) || {};
  513. // Will fetch userAgent if called from browser sdk
  514. const { userAgent } = utils.GLOBAL_OBJ.navigator || {};
  515. const session$1 = session.makeSession({
  516. release,
  517. environment,
  518. user: scope.getUser(),
  519. ...(userAgent && { userAgent }),
  520. ...context,
  521. });
  522. // End existing session if there's one
  523. const currentSession = scope.getSession && scope.getSession();
  524. if (currentSession && currentSession.status === 'ok') {
  525. session.updateSession(currentSession, { status: 'exited' });
  526. }
  527. // eslint-disable-next-line deprecation/deprecation
  528. this.endSession();
  529. // Afterwards we set the new session on the scope
  530. scope.setSession(session$1);
  531. return session$1;
  532. }
  533. /**
  534. * Returns if default PII should be sent to Sentry and propagated in ourgoing requests
  535. * when Tracing is used.
  536. *
  537. * @deprecated Use top-level `getClient().getOptions().sendDefaultPii` instead. This function
  538. * only unnecessarily increased API surface but only wrapped accessing the option.
  539. */
  540. shouldSendDefaultPii() {
  541. // eslint-disable-next-line deprecation/deprecation
  542. const client = this.getClient();
  543. const options = client && client.getOptions();
  544. return Boolean(options && options.sendDefaultPii);
  545. }
  546. /**
  547. * Sends the current Session on the scope
  548. */
  549. _sendSessionUpdate() {
  550. // eslint-disable-next-line deprecation/deprecation
  551. const { scope, client } = this.getStackTop();
  552. const session = scope.getSession();
  553. if (session && client && client.captureSession) {
  554. client.captureSession(session);
  555. }
  556. }
  557. /**
  558. * Calls global extension method and binding current instance to the function call
  559. */
  560. // @ts-expect-error Function lacks ending return statement and return type does not include 'undefined'. ts(2366)
  561. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  562. _callExtensionMethod(method, ...args) {
  563. const carrier = getMainCarrier();
  564. const sentry = carrier.__SENTRY__;
  565. if (sentry && sentry.extensions && typeof sentry.extensions[method] === 'function') {
  566. return sentry.extensions[method].apply(this, args);
  567. }
  568. debugBuild.DEBUG_BUILD && utils.logger.warn(`Extension method ${method} couldn't be found, doing nothing.`);
  569. }
  570. }
  571. /**
  572. * Returns the global shim registry.
  573. *
  574. * FIXME: This function is problematic, because despite always returning a valid Carrier,
  575. * it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check
  576. * at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.
  577. **/
  578. function getMainCarrier() {
  579. utils.GLOBAL_OBJ.__SENTRY__ = utils.GLOBAL_OBJ.__SENTRY__ || {
  580. extensions: {},
  581. hub: undefined,
  582. };
  583. return utils.GLOBAL_OBJ;
  584. }
  585. /**
  586. * Replaces the current main hub with the passed one on the global object
  587. *
  588. * @returns The old replaced hub
  589. *
  590. * @deprecated Use `setCurrentClient()` instead.
  591. */
  592. function makeMain(hub) {
  593. const registry = getMainCarrier();
  594. const oldHub = getHubFromCarrier(registry);
  595. setHubOnCarrier(registry, hub);
  596. return oldHub;
  597. }
  598. /**
  599. * Returns the default hub instance.
  600. *
  601. * If a hub is already registered in the global carrier but this module
  602. * contains a more recent version, it replaces the registered version.
  603. * Otherwise, the currently registered hub will be returned.
  604. *
  605. * @deprecated Use the respective replacement method directly instead.
  606. */
  607. function getCurrentHub() {
  608. // Get main carrier (global for every environment)
  609. const registry = getMainCarrier();
  610. if (registry.__SENTRY__ && registry.__SENTRY__.acs) {
  611. const hub = registry.__SENTRY__.acs.getCurrentHub();
  612. if (hub) {
  613. return hub;
  614. }
  615. }
  616. // Return hub that lives on a global object
  617. return getGlobalHub(registry);
  618. }
  619. /**
  620. * Get the currently active isolation scope.
  621. * The isolation scope is active for the current exection context,
  622. * meaning that it will remain stable for the same Hub.
  623. */
  624. function getIsolationScope() {
  625. // eslint-disable-next-line deprecation/deprecation
  626. return getCurrentHub().getIsolationScope();
  627. }
  628. function getGlobalHub(registry = getMainCarrier()) {
  629. // If there's no hub, or its an old API, assign a new one
  630. if (
  631. !hasHubOnCarrier(registry) ||
  632. // eslint-disable-next-line deprecation/deprecation
  633. getHubFromCarrier(registry).isOlderThan(API_VERSION)
  634. ) {
  635. // eslint-disable-next-line deprecation/deprecation
  636. setHubOnCarrier(registry, new Hub());
  637. }
  638. // Return hub that lives on a global object
  639. return getHubFromCarrier(registry);
  640. }
  641. /**
  642. * @private Private API with no semver guarantees!
  643. *
  644. * If the carrier does not contain a hub, a new hub is created with the global hub client and scope.
  645. */
  646. function ensureHubOnCarrier(carrier, parent = getGlobalHub()) {
  647. // If there's no hub on current domain, or it's an old API, assign a new one
  648. if (
  649. !hasHubOnCarrier(carrier) ||
  650. // eslint-disable-next-line deprecation/deprecation
  651. getHubFromCarrier(carrier).isOlderThan(API_VERSION)
  652. ) {
  653. // eslint-disable-next-line deprecation/deprecation
  654. const client = parent.getClient();
  655. // eslint-disable-next-line deprecation/deprecation
  656. const scope = parent.getScope();
  657. // eslint-disable-next-line deprecation/deprecation
  658. const isolationScope = parent.getIsolationScope();
  659. // eslint-disable-next-line deprecation/deprecation
  660. setHubOnCarrier(carrier, new Hub(client, scope.clone(), isolationScope.clone()));
  661. }
  662. }
  663. /**
  664. * @private Private API with no semver guarantees!
  665. *
  666. * Sets the global async context strategy
  667. */
  668. function setAsyncContextStrategy(strategy) {
  669. // Get main carrier (global for every environment)
  670. const registry = getMainCarrier();
  671. registry.__SENTRY__ = registry.__SENTRY__ || {};
  672. registry.__SENTRY__.acs = strategy;
  673. }
  674. /**
  675. * Runs the supplied callback in its own async context. Async Context strategies are defined per SDK.
  676. *
  677. * @param callback The callback to run in its own async context
  678. * @param options Options to pass to the async context strategy
  679. * @returns The result of the callback
  680. */
  681. function runWithAsyncContext(callback, options = {}) {
  682. const registry = getMainCarrier();
  683. if (registry.__SENTRY__ && registry.__SENTRY__.acs) {
  684. return registry.__SENTRY__.acs.runWithAsyncContext(callback, options);
  685. }
  686. // if there was no strategy, fallback to just calling the callback
  687. return callback();
  688. }
  689. /**
  690. * This will tell whether a carrier has a hub on it or not
  691. * @param carrier object
  692. */
  693. function hasHubOnCarrier(carrier) {
  694. return !!(carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub);
  695. }
  696. /**
  697. * This will create a new {@link Hub} and add to the passed object on
  698. * __SENTRY__.hub.
  699. * @param carrier object
  700. * @hidden
  701. */
  702. function getHubFromCarrier(carrier) {
  703. // eslint-disable-next-line deprecation/deprecation
  704. return utils.getGlobalSingleton('hub', () => new Hub(), carrier);
  705. }
  706. /**
  707. * This will set passed {@link Hub} on the passed object's __SENTRY__.hub attribute
  708. * @param carrier object
  709. * @param hub Hub
  710. * @returns A boolean indicating success or failure
  711. */
  712. function setHubOnCarrier(carrier, hub) {
  713. if (!carrier) return false;
  714. const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {});
  715. __SENTRY__.hub = hub;
  716. return true;
  717. }
  718. exports.API_VERSION = API_VERSION;
  719. exports.Hub = Hub;
  720. exports.ensureHubOnCarrier = ensureHubOnCarrier;
  721. exports.getCurrentHub = getCurrentHub;
  722. exports.getHubFromCarrier = getHubFromCarrier;
  723. exports.getIsolationScope = getIsolationScope;
  724. exports.getMainCarrier = getMainCarrier;
  725. exports.makeMain = makeMain;
  726. exports.runWithAsyncContext = runWithAsyncContext;
  727. exports.setAsyncContextStrategy = setAsyncContextStrategy;
  728. exports.setHubOnCarrier = setHubOnCarrier;
  729. //# sourceMappingURL=hub.js.map