hub.js 23 KB

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