@@ -19,15 +19,7 @@ import type {
1919 TransactionContext ,
2020 User ,
2121} from '@sentry/types' ;
22- import {
23- GLOBAL_OBJ ,
24- consoleSandbox ,
25- dateTimestampInSeconds ,
26- getGlobalSingleton ,
27- isThenable ,
28- logger ,
29- uuid4 ,
30- } from '@sentry/utils' ;
22+ import { GLOBAL_OBJ , consoleSandbox , dateTimestampInSeconds , isThenable , logger , uuid4 } from '@sentry/utils' ;
3123
3224import { DEFAULT_ENVIRONMENT } from './constants' ;
3325import { DEBUG_BUILD } from './debug-build' ;
@@ -86,21 +78,41 @@ export interface Layer {
8678 * @hidden
8779 */
8880export interface Carrier {
89- __SENTRY__ ?: {
90- hub ?: Hub ;
91- acs ?: AsyncContextStrategy ;
92- /**
93- * Extra Hub properties injected by various SDKs
94- */
95- integrations ?: Integration [ ] ;
96- extensions ?: {
97- /** Extension methods for the hub, which are bound to the current Hub instance */
98- // eslint-disable-next-line @typescript-eslint/ban-types
99- [ key : string ] : Function ;
100- } ;
81+ __SENTRY__ ?: SentryCarrier ;
82+ }
83+
84+ type CreateHub = ( ...options : ConstructorParameters < typeof Hub > ) => Hub ;
85+
86+ interface SentryCarrier {
87+ hub ?: Hub ;
88+ createHub ?: CreateHub ;
89+ acs ?: AsyncContextStrategy ;
90+ /**
91+ * Extra Hub properties injected by various SDKs
92+ */
93+ integrations ?: Integration [ ] ;
94+ extensions ?: {
95+ /** Extension methods for the hub, which are bound to the current Hub instance */
96+ // eslint-disable-next-line @typescript-eslint/ban-types
97+ [ key : string ] : Function ;
10198 } ;
10299}
103100
101+ /**
102+ * Create a hub. If a custom `createHub` is registered on the main carrier, use that instead.
103+ * This only exists to make POTEL migration easier.
104+ */
105+ function createHub ( ...options : ConstructorParameters < typeof Hub > ) : Hub {
106+ const carrier = getMainCarrier ( ) ;
107+ const sentry = getSentryCarrier ( carrier ) ;
108+
109+ if ( sentry . createHub ) {
110+ return sentry . createHub ( ...options ) ;
111+ }
112+
113+ return new Hub ( ...options ) ;
114+ }
115+
104116/**
105117 * @inheritDoc
106118 */
@@ -663,8 +675,8 @@ Sentry.init({...});
663675 // eslint-disable-next-line @typescript-eslint/no-explicit-any
664676 private _callExtensionMethod < T > ( method : string , ...args : any [ ] ) : T {
665677 const carrier = getMainCarrier ( ) ;
666- const sentry = carrier . __SENTRY__ ;
667- if ( sentry && sentry . extensions && typeof sentry . extensions [ method ] === 'function' ) {
678+ const sentry = getSentryCarrier ( carrier ) ;
679+ if ( sentry . extensions && typeof sentry . extensions [ method ] === 'function' ) {
668680 return sentry . extensions [ method ] . apply ( this , args ) ;
669681 }
670682 DEBUG_BUILD && logger . warn ( `Extension method ${ method } couldn't be found, doing nothing.` ) ;
@@ -679,10 +691,8 @@ Sentry.init({...});
679691 * at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.
680692 **/
681693export function getMainCarrier ( ) : Carrier {
682- GLOBAL_OBJ . __SENTRY__ = GLOBAL_OBJ . __SENTRY__ || {
683- extensions : { } ,
684- hub : undefined ,
685- } ;
694+ // This ensures a Sentry carrier exists
695+ getSentryCarrier ( GLOBAL_OBJ ) ;
686696 return GLOBAL_OBJ ;
687697}
688698
@@ -711,18 +721,19 @@ export function makeMain(hub: Hub): Hub {
711721 */
712722export function getCurrentHub ( ) : Hub {
713723 // Get main carrier (global for every environment)
714- const registry = getMainCarrier ( ) ;
724+ const carrier = getMainCarrier ( ) ;
725+ const sentry = getSentryCarrier ( carrier ) ;
715726
716- if ( registry . __SENTRY__ && registry . __SENTRY__ . acs ) {
717- const hub = registry . __SENTRY__ . acs . getCurrentHub ( ) ;
727+ if ( sentry . acs ) {
728+ const hub = sentry . acs . getCurrentHub ( ) ;
718729
719730 if ( hub ) {
720731 return hub ;
721732 }
722733 }
723734
724735 // Return hub that lives on a global object
725- return getGlobalHub ( registry ) ;
736+ return getGlobalHub ( ) ;
726737}
727738
728739/**
@@ -735,15 +746,17 @@ export function getIsolationScope(): Scope {
735746 return getCurrentHub ( ) . getIsolationScope ( ) ;
736747}
737748
738- function getGlobalHub ( registry : Carrier = getMainCarrier ( ) ) : Hub {
749+ function getGlobalHub ( ) : Hub {
750+ const registry = getMainCarrier ( ) ;
751+
739752 // If there's no hub, or its an old API, assign a new one
740753
741754 if (
742755 ! hasHubOnCarrier ( registry ) ||
743756 // eslint-disable-next-line deprecation/deprecation
744757 getHubFromCarrier ( registry ) . isOlderThan ( API_VERSION )
745758 ) {
746- setHubOnCarrier ( registry , new Hub ( ) ) ;
759+ setHubOnCarrier ( registry , createHub ( ) ) ;
747760 }
748761
749762 // Return hub that lives on a global object
@@ -768,7 +781,7 @@ export function ensureHubOnCarrier(carrier: Carrier, parent: Hub = getGlobalHub(
768781 const scope = parent . getScope ( ) ;
769782 // eslint-disable-next-line deprecation/deprecation
770783 const isolationScope = parent . getIsolationScope ( ) ;
771- setHubOnCarrier ( carrier , new Hub ( client , scope . clone ( ) , isolationScope . clone ( ) ) ) ;
784+ setHubOnCarrier ( carrier , createHub ( client , scope . clone ( ) , isolationScope . clone ( ) ) ) ;
772785 }
773786}
774787
@@ -780,8 +793,8 @@ export function ensureHubOnCarrier(carrier: Carrier, parent: Hub = getGlobalHub(
780793export function setAsyncContextStrategy ( strategy : AsyncContextStrategy | undefined ) : void {
781794 // Get main carrier (global for every environment)
782795 const registry = getMainCarrier ( ) ;
783- registry . __SENTRY__ = registry . __SENTRY__ || { } ;
784- registry . __SENTRY__ . acs = strategy ;
796+ const sentry = getSentryCarrier ( registry ) ;
797+ sentry . acs = strategy ;
785798}
786799
787800/**
@@ -793,9 +806,10 @@ export function setAsyncContextStrategy(strategy: AsyncContextStrategy | undefin
793806 */
794807export function runWithAsyncContext < T > ( callback : ( ) => T , options : RunWithAsyncContextOptions = { } ) : T {
795808 const registry = getMainCarrier ( ) ;
809+ const sentry = getSentryCarrier ( registry ) ;
796810
797- if ( registry . __SENTRY__ && registry . __SENTRY__ . acs ) {
798- return registry . __SENTRY__ . acs . runWithAsyncContext ( callback , options ) ;
811+ if ( sentry . acs ) {
812+ return sentry . acs . runWithAsyncContext ( callback , options ) ;
799813 }
800814
801815 // if there was no strategy, fallback to just calling the callback
@@ -807,7 +821,7 @@ export function runWithAsyncContext<T>(callback: () => T, options: RunWithAsyncC
807821 * @param carrier object
808822 */
809823function hasHubOnCarrier ( carrier : Carrier ) : boolean {
810- return ! ! ( carrier && carrier . __SENTRY__ && carrier . __SENTRY__ . hub ) ;
824+ return ! ! getSentryCarrier ( carrier ) . hub ;
811825}
812826
813827/**
@@ -817,7 +831,12 @@ function hasHubOnCarrier(carrier: Carrier): boolean {
817831 * @hidden
818832 */
819833export function getHubFromCarrier ( carrier : Carrier ) : Hub {
820- return getGlobalSingleton < Hub > ( 'hub' , ( ) => new Hub ( ) , carrier ) ;
834+ const sentry = getSentryCarrier ( carrier ) ;
835+ if ( ! sentry . hub ) {
836+ sentry . hub = createHub ( ) ;
837+ }
838+
839+ return sentry . hub ;
821840}
822841
823842/**
@@ -828,7 +847,18 @@ export function getHubFromCarrier(carrier: Carrier): Hub {
828847 */
829848export function setHubOnCarrier ( carrier : Carrier , hub : Hub ) : boolean {
830849 if ( ! carrier ) return false ;
831- const __SENTRY__ = ( carrier . __SENTRY__ = carrier . __SENTRY__ || { } ) ;
832- __SENTRY__ . hub = hub ;
850+ const sentry = getSentryCarrier ( carrier ) ;
851+ sentry . hub = hub ;
833852 return true ;
834853}
854+
855+ /** Will either get the existing sentry carrier, or create a new one. */
856+ function getSentryCarrier ( carrier : Carrier ) : SentryCarrier {
857+ if ( ! carrier . __SENTRY__ ) {
858+ carrier . __SENTRY__ = {
859+ extensions : { } ,
860+ hub : undefined ,
861+ } ;
862+ }
863+ return carrier . __SENTRY__ ;
864+ }
0 commit comments