@sentry/react 10.36.0 → 10.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -130,12 +130,12 @@ function hoistNonReactStatics
130
130
  const sourceStatics = getStatics(sourceComponent);
131
131
 
132
132
  for (const key of keys) {
133
- const keyStr = String(key);
133
+ // Use key directly - String(key) throws for Symbols if minified to '' + key (#18966)
134
134
  if (
135
- !KNOWN_STATICS[keyStr ] &&
135
+ !KNOWN_STATICS[key ] &&
136
136
  true &&
137
- !sourceStatics?.[keyStr] &&
138
- !targetStatics?.[keyStr] &&
137
+ !sourceStatics?.[key ] &&
138
+ !targetStatics?.[key ] &&
139
139
  !getOwnPropertyDescriptor(targetComponent, key) // Don't overwrite existing properties
140
140
  ) {
141
141
  const descriptor = getOwnPropertyDescriptor(sourceComponent, key);
@@ -1 +1 @@
1
- {"version":3,"file":"hoist-non-react-statics.js","sources":["../../src/hoist-non-react-statics.ts"],"sourcesContent":["/**\n * Inlined implementation of hoist-non-react-statics\n * Original library: https://github.com/mridgway/hoist-non-react-statics\n * License: BSD-3-Clause\n * Copyright 2015, Yahoo! Inc.\n *\n * This is an inlined version to avoid ESM compatibility issues with the original package.\n */\n\nimport type * as React from 'react';\n\n/**\n * React statics that should not be hoisted\n */\nconst REACT_STATICS = {\n childContextTypes: true,\n contextType: true,\n contextTypes: true,\n defaultProps: true,\n displayName: true,\n getDefaultProps: true,\n getDerivedStateFromError: true,\n getDerivedStateFromProps: true,\n mixins: true,\n propTypes: true,\n type: true,\n} as const;\n\n/**\n * Known JavaScript function statics that should not be hoisted\n */\nconst KNOWN_STATICS = {\n name: true,\n length: true,\n prototype: true,\n caller: true,\n callee: true,\n arguments: true,\n arity: true,\n} as const;\n\n/**\n * Statics specific to ForwardRef components\n */\nconst FORWARD_REF_STATICS = {\n $$typeof: true,\n render: true,\n defaultProps: true,\n displayName: true,\n propTypes: true,\n} as const;\n\n/**\n * Statics specific to Memo components\n */\nconst MEMO_STATICS = {\n $$typeof: true,\n compare: true,\n defaultProps: true,\n displayName: true,\n propTypes: true,\n type: true,\n} as const;\n\n/**\n * Inlined react-is utilities\n * We only need to detect ForwardRef and Memo types\n */\nconst ForwardRefType = Symbol.for('react.forward_ref');\nconst MemoType = Symbol.for('react.memo');\n\n/**\n * Check if a component is a Memo component\n */\nfunction isMemo(component: unknown): boolean {\n return (\n typeof component === 'object' && component !== null && (component as { $$typeof?: symbol }).$$typeof === MemoType\n );\n}\n\n/**\n * Map of React component types to their specific statics\n */\nconst TYPE_STATICS: Record<symbol, Record<string, boolean>> = {};\nTYPE_STATICS[ForwardRefType] = FORWARD_REF_STATICS;\nTYPE_STATICS[MemoType] = MEMO_STATICS;\n\n/**\n * Get the appropriate statics object for a given component\n */\nfunction getStatics(component: React.ComponentType<unknown>): Record<string, boolean> {\n // React v16.11 and below\n if (isMemo(component)) {\n return MEMO_STATICS;\n }\n\n // React v16.12 and above\n const componentType = (component as { $$typeof?: symbol }).$$typeof;\n return (componentType && TYPE_STATICS[componentType]) || REACT_STATICS;\n}\n\nconst defineProperty = Object.defineProperty.bind(Object);\nconst getOwnPropertyNames = Object.getOwnPropertyNames.bind(Object);\nconst getOwnPropertySymbols = Object.getOwnPropertySymbols?.bind(Object);\nconst getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor.bind(Object);\nconst getPrototypeOf = Object.getPrototypeOf.bind(Object);\nconst objectPrototype = Object.prototype;\n\n/**\n * Copies non-react specific statics from a child component to a parent component.\n * Similar to Object.assign, but copies all static properties from source to target,\n * excluding React-specific statics and known JavaScript statics.\n *\n * @param targetComponent - The component to copy statics to\n * @param sourceComponent - The component to copy statics from\n * @param excludelist - An optional object of keys to exclude from hoisting\n * @returns The target component with hoisted statics\n */\nexport function hoistNonReactStatics<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends React.ComponentType<any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n S extends React.ComponentType<any>,\n C extends Record<string, boolean> = Record<string, never>,\n>(targetComponent: T, sourceComponent: S, excludelist?: C): T {\n if (typeof sourceComponent !== 'string') {\n // Don't hoist over string (html) components\n if (objectPrototype) {\n const inheritedComponent = getPrototypeOf(sourceComponent);\n\n if (inheritedComponent && inheritedComponent !== objectPrototype) {\n hoistNonReactStatics(targetComponent, inheritedComponent, excludelist);\n }\n }\n\n let keys: (string | symbol)[] = getOwnPropertyNames(sourceComponent);\n\n if (getOwnPropertySymbols) {\n keys = keys.concat(getOwnPropertySymbols(sourceComponent));\n }\n\n const targetStatics = getStatics(targetComponent);\n const sourceStatics = getStatics(sourceComponent);\n\n for (const key of keys) {\n const keyStr = String(key);\n if (\n !KNOWN_STATICS[keyStr as keyof typeof KNOWN_STATICS] &&\n !excludelist?.[keyStr] &&\n !sourceStatics?.[keyStr] &&\n !targetStatics?.[keyStr] &&\n !getOwnPropertyDescriptor(targetComponent, key) // Don't overwrite existing properties\n ) {\n const descriptor = getOwnPropertyDescriptor(sourceComponent, key);\n\n if (descriptor) {\n try {\n // Avoid failures from read-only properties\n defineProperty(targetComponent, key, descriptor);\n } catch (e) {\n // Silently ignore errors\n }\n }\n }\n }\n }\n\n return targetComponent;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hoist-non-react-statics.js","sources":["../../src/hoist-non-react-statics.ts"],"sourcesContent":["/**\n * Inlined implementation of hoist-non-react-statics\n * Original library: https://github.com/mridgway/hoist-non-react-statics\n * License: BSD-3-Clause\n * Copyright 2015, Yahoo! Inc.\n *\n * This is an inlined version to avoid ESM compatibility issues with the original package.\n */\n\nimport type * as React from 'react';\n\n/**\n * React statics that should not be hoisted\n */\nconst REACT_STATICS = {\n childContextTypes: true,\n contextType: true,\n contextTypes: true,\n defaultProps: true,\n displayName: true,\n getDefaultProps: true,\n getDerivedStateFromError: true,\n getDerivedStateFromProps: true,\n mixins: true,\n propTypes: true,\n type: true,\n} as const;\n\n/**\n * Known JavaScript function statics that should not be hoisted\n */\nconst KNOWN_STATICS = {\n name: true,\n length: true,\n prototype: true,\n caller: true,\n callee: true,\n arguments: true,\n arity: true,\n} as const;\n\n/**\n * Statics specific to ForwardRef components\n */\nconst FORWARD_REF_STATICS = {\n $$typeof: true,\n render: true,\n defaultProps: true,\n displayName: true,\n propTypes: true,\n} as const;\n\n/**\n * Statics specific to Memo components\n */\nconst MEMO_STATICS = {\n $$typeof: true,\n compare: true,\n defaultProps: true,\n displayName: true,\n propTypes: true,\n type: true,\n} as const;\n\n/**\n * Inlined react-is utilities\n * We only need to detect ForwardRef and Memo types\n */\nconst ForwardRefType = Symbol.for('react.forward_ref');\nconst MemoType = Symbol.for('react.memo');\n\n/**\n * Check if a component is a Memo component\n */\nfunction isMemo(component: unknown): boolean {\n return (\n typeof component === 'object' && component !== null && (component as { $$typeof?: symbol }).$$typeof === MemoType\n );\n}\n\n/**\n * Map of React component types to their specific statics\n */\nconst TYPE_STATICS: Record<symbol, Record<string, boolean>> = {};\nTYPE_STATICS[ForwardRefType] = FORWARD_REF_STATICS;\nTYPE_STATICS[MemoType] = MEMO_STATICS;\n\n/**\n * Get the appropriate statics object for a given component\n */\nfunction getStatics(component: React.ComponentType<unknown>): Record<string, boolean> {\n // React v16.11 and below\n if (isMemo(component)) {\n return MEMO_STATICS;\n }\n\n // React v16.12 and above\n const componentType = (component as { $$typeof?: symbol }).$$typeof;\n return (componentType && TYPE_STATICS[componentType]) || REACT_STATICS;\n}\n\nconst defineProperty = Object.defineProperty.bind(Object);\nconst getOwnPropertyNames = Object.getOwnPropertyNames.bind(Object);\nconst getOwnPropertySymbols = Object.getOwnPropertySymbols?.bind(Object);\nconst getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor.bind(Object);\nconst getPrototypeOf = Object.getPrototypeOf.bind(Object);\nconst objectPrototype = Object.prototype;\n\n/**\n * Copies non-react specific statics from a child component to a parent component.\n * Similar to Object.assign, but copies all static properties from source to target,\n * excluding React-specific statics and known JavaScript statics.\n *\n * @param targetComponent - The component to copy statics to\n * @param sourceComponent - The component to copy statics from\n * @param excludelist - An optional object of keys to exclude from hoisting\n * @returns The target component with hoisted statics\n */\nexport function hoistNonReactStatics<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends React.ComponentType<any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n S extends React.ComponentType<any>,\n C extends Record<string, boolean> = Record<string, never>,\n>(targetComponent: T, sourceComponent: S, excludelist?: C): T {\n if (typeof sourceComponent !== 'string') {\n // Don't hoist over string (html) components\n if (objectPrototype) {\n const inheritedComponent = getPrototypeOf(sourceComponent);\n\n if (inheritedComponent && inheritedComponent !== objectPrototype) {\n hoistNonReactStatics(targetComponent, inheritedComponent, excludelist);\n }\n }\n\n let keys: (string | symbol)[] = getOwnPropertyNames(sourceComponent);\n\n if (getOwnPropertySymbols) {\n keys = keys.concat(getOwnPropertySymbols(sourceComponent));\n }\n\n const targetStatics = getStatics(targetComponent);\n const sourceStatics = getStatics(sourceComponent);\n\n for (const key of keys) {\n // Use key directly - String(key) throws for Symbols if minified to '' + key (#18966)\n if (\n !KNOWN_STATICS[key as keyof typeof KNOWN_STATICS] &&\n !(excludelist && excludelist[key as keyof C]) &&\n !sourceStatics?.[key as string] &&\n !targetStatics?.[key as string] &&\n !getOwnPropertyDescriptor(targetComponent, key) // Don't overwrite existing properties\n ) {\n const descriptor = getOwnPropertyDescriptor(sourceComponent, key);\n\n if (descriptor) {\n try {\n // Avoid failures from read-only properties\n defineProperty(targetComponent, key, descriptor);\n } catch (e) {\n // Silently ignore errors\n }\n }\n }\n }\n }\n\n return targetComponent;\n}\n"],"names":[],"mappings":"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"}
@@ -35,6 +35,9 @@ const allRoutes = new Set();
35
35
  // Tracks lazy route loads to wait before finalizing span names
36
36
  const pendingLazyRouteLoads = new WeakMap();
37
37
 
38
+ // Tracks deferred lazy route promises that can be resolved when patchRoutesOnNavigation is called
39
+ const deferredLazyRouteResolvers = new WeakMap();
40
+
38
41
  /**
39
42
  * Schedules a callback using requestAnimationFrame when available (browser),
40
43
  * or falls back to setTimeout for SSR environments (Node.js, createMemoryRouter tests).
@@ -160,6 +163,34 @@ function trackLazyRouteLoad(span, promise) {
160
163
  });
161
164
  }
162
165
 
166
+ /**
167
+ * Creates a deferred promise for a span that will be resolved when patchRoutesOnNavigation is called.
168
+ * This ensures that patchedEnd waits for patchRoutesOnNavigation to be called before ending the span.
169
+ */
170
+ function createDeferredLazyRoutePromise(span) {
171
+ const deferredPromise = new Promise(resolve => {
172
+ deferredLazyRouteResolvers.set(span, resolve);
173
+ });
174
+
175
+ trackLazyRouteLoad(span, deferredPromise);
176
+ }
177
+
178
+ /**
179
+ * Resolves the deferred lazy route promise for a span.
180
+ * Called when patchRoutesOnNavigation is invoked.
181
+ */
182
+ function resolveDeferredLazyRoutePromise(span) {
183
+ const resolver = deferredLazyRouteResolvers.get(span);
184
+ if (resolver) {
185
+ resolver();
186
+ deferredLazyRouteResolvers.delete(span);
187
+ // Clear the flag so patchSpanEnd doesn't wait unnecessarily for routes that have already loaded
188
+ if ((span ).__sentry_may_have_lazy_routes__) {
189
+ (span ).__sentry_may_have_lazy_routes__ = false;
190
+ }
191
+ }
192
+ }
193
+
163
194
  /**
164
195
  * Processes resolved routes by adding them to allRoutes and checking for nested async handlers.
165
196
  * When capturedSpan is provided, updates that specific span instead of the current active span.
@@ -380,10 +411,30 @@ function createV6CompatibleWrapCreateBrowserRouter
380
411
  }
381
412
  }
382
413
 
383
- const wrappedOpts = wrapPatchRoutesOnNavigation(opts);
414
+ // Capture the active span BEFORE creating the router.
415
+ // This is important because the span might end (due to idle timeout) before
416
+ // patchRoutesOnNavigation is called by React Router.
417
+ const activeRootSpan = utils.getActiveRootSpan();
418
+
419
+ // If patchRoutesOnNavigation is provided and we have an active span,
420
+ // mark the span as having potential lazy routes and create a deferred promise.
421
+ const hasPatchRoutesOnNavigation =
422
+ opts && 'patchRoutesOnNavigation' in opts && typeof opts.patchRoutesOnNavigation === 'function';
423
+ if (hasPatchRoutesOnNavigation && activeRootSpan) {
424
+ // Mark the span as potentially having lazy routes
425
+ core.addNonEnumerableProperty(
426
+ activeRootSpan ,
427
+ '__sentry_may_have_lazy_routes__',
428
+ true,
429
+ );
430
+ createDeferredLazyRoutePromise(activeRootSpan);
431
+ }
432
+
433
+ // Pass the captured span to wrapPatchRoutesOnNavigation so it uses the same span
434
+ // even if the span has ended by the time patchRoutesOnNavigation is called.
435
+ const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan);
384
436
  const router = createRouterFunction(routes, wrappedOpts);
385
437
  const basename = opts?.basename;
386
- const activeRootSpan = utils.getActiveRootSpan();
387
438
 
388
439
  if (router.state.historyAction === 'POP' && activeRootSpan) {
389
440
  updatePageloadTransaction({
@@ -433,7 +484,23 @@ function createV6CompatibleWrapCreateMemoryRouter
433
484
  }
434
485
  }
435
486
 
436
- const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true);
487
+ // Capture the active span BEFORE creating the router (same as browser router)
488
+ const memoryActiveRootSpanEarly = utils.getActiveRootSpan();
489
+
490
+ // If patchRoutesOnNavigation is provided and we have an active span,
491
+ // mark the span as having potential lazy routes and create a deferred promise.
492
+ const hasPatchRoutesOnNavigation =
493
+ opts && 'patchRoutesOnNavigation' in opts && typeof opts.patchRoutesOnNavigation === 'function';
494
+ if (hasPatchRoutesOnNavigation && memoryActiveRootSpanEarly) {
495
+ core.addNonEnumerableProperty(
496
+ memoryActiveRootSpanEarly ,
497
+ '__sentry_may_have_lazy_routes__',
498
+ true,
499
+ );
500
+ createDeferredLazyRoutePromise(memoryActiveRootSpanEarly);
501
+ }
502
+
503
+ const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly);
437
504
 
438
505
  const router = createRouterFunction(routes, wrappedOpts);
439
506
  const basename = opts?.basename;
@@ -626,10 +693,10 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
626
693
  return React.createElement(SentryRoutes, { routes: routes, locationArg: locationArg,} );
627
694
  };
628
695
  }
629
-
630
696
  function wrapPatchRoutesOnNavigation(
631
697
  opts,
632
698
  isMemoryRouter = false,
699
+ capturedSpan,
633
700
  ) {
634
701
  if (!opts || !('patchRoutesOnNavigation' in opts) || typeof opts.patchRoutesOnNavigation !== 'function') {
635
702
  return opts || {};
@@ -642,24 +709,58 @@ function wrapPatchRoutesOnNavigation(
642
709
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
643
710
  const targetPath = (args )?.path;
644
711
 
645
- const activeRootSpan = utils.getActiveRootSpan();
712
+ // Use current active span if available, otherwise fall back to captured span (from router creation time).
713
+ // This ensures navigation spans use their own span (not the stale pageload span), while still
714
+ // supporting pageload spans that may have ended before patchRoutesOnNavigation is called.
715
+ const activeRootSpan = utils.getActiveRootSpan() ?? capturedSpan;
646
716
 
647
717
  if (!isMemoryRouter) {
648
718
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
649
719
  const originalPatch = (args )?.patch;
720
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
721
+ const matches = (args )?.matches ;
650
722
  if (originalPatch) {
651
723
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
652
724
  (args ).patch = (routeId, children) => {
653
725
  addRoutesToAllRoutes(children);
654
- const currentActiveRootSpan = utils.getActiveRootSpan();
655
- // Only update if we have a valid targetPath (patchRoutesOnNavigation can be called without path)
726
+
727
+ // Find the parent route from matches and attach children to it in allRoutes.
728
+ // React Router's patch attaches children to its internal route copies, but we need
729
+ // to update the route objects in our allRoutes Set for proper route matching.
730
+ if (matches && matches.length > 0) {
731
+ const leafMatch = matches[matches.length - 1];
732
+ const leafRoute = leafMatch?.route;
733
+ if (leafRoute) {
734
+ // Find the matching route in allRoutes by id, reference, or path
735
+ const matchingRoute = Array.from(allRoutes).find(route => {
736
+ const idMatches = route.id !== undefined && route.id === routeId;
737
+ const referenceMatches = route === leafRoute;
738
+ const pathMatches =
739
+ route.path !== undefined && leafRoute.path !== undefined && route.path === leafRoute.path;
740
+
741
+ return idMatches || referenceMatches || pathMatches;
742
+ });
743
+
744
+ if (matchingRoute) {
745
+ addResolvedRoutesToParent(children, matchingRoute);
746
+ }
747
+ }
748
+ }
749
+
750
+ // Use the captured activeRootSpan instead of getActiveRootSpan() to avoid race conditions
751
+ // where user navigates away during lazy route loading and we'd update the wrong span
752
+ const spanJson = activeRootSpan ? core.spanToJSON(activeRootSpan) : undefined;
753
+ // Only update if we have a valid targetPath (patchRoutesOnNavigation can be called without path),
754
+ // the captured span exists, hasn't ended, and is a navigation span
656
755
  if (
657
756
  targetPath &&
658
- currentActiveRootSpan &&
659
- (core.spanToJSON(currentActiveRootSpan) ).op === 'navigation'
757
+ activeRootSpan &&
758
+ spanJson &&
759
+ !spanJson.timestamp && // Span hasn't ended yet
760
+ spanJson.op === 'navigation'
660
761
  ) {
661
762
  updateNavigationSpan(
662
- currentActiveRootSpan,
763
+ activeRootSpan,
663
764
  { pathname: targetPath, search: '', hash: '', state: null, key: 'default' },
664
765
  Array.from(allRoutes),
665
766
  true,
@@ -679,15 +780,29 @@ function wrapPatchRoutesOnNavigation(
679
780
  result = await originalPatchRoutes(args);
680
781
  } finally {
681
782
  utils.clearNavigationContext(contextToken);
783
+ // Resolve the deferred promise now that patchRoutesOnNavigation has completed.
784
+ // This ensures patchedEnd has waited long enough for the lazy routes to load.
785
+ if (activeRootSpan) {
786
+ resolveDeferredLazyRoutePromise(activeRootSpan);
787
+ }
682
788
  }
683
789
 
684
- const currentActiveRootSpan = utils.getActiveRootSpan();
685
- if (currentActiveRootSpan && (core.spanToJSON(currentActiveRootSpan) ).op === 'navigation') {
686
- const pathname = isMemoryRouter ? targetPath : targetPath || browser.WINDOW.location?.pathname;
790
+ // Use the captured activeRootSpan instead of getActiveRootSpan() to avoid race conditions
791
+ // where user navigates away during lazy route loading and we'd update the wrong span
792
+ const spanJson = activeRootSpan ? core.spanToJSON(activeRootSpan) : undefined;
793
+ if (
794
+ activeRootSpan &&
795
+ spanJson &&
796
+ !spanJson.timestamp && // Span hasn't ended yet
797
+ spanJson.op === 'navigation'
798
+ ) {
799
+ // Use targetPath consistently - don't fall back to WINDOW.location which may have changed
800
+ // if the user navigated away during async loading
801
+ const pathname = targetPath;
687
802
 
688
803
  if (pathname) {
689
804
  updateNavigationSpan(
690
- currentActiveRootSpan,
805
+ activeRootSpan,
691
806
  { pathname, search: '', hash: '', state: null, key: 'default' },
692
807
  Array.from(allRoutes),
693
808
  false,
@@ -808,7 +923,7 @@ function handleNavigation(opts
808
923
  pathname: location.pathname,
809
924
  locationKey,
810
925
  });
811
- patchSpanEnd(navigationSpan, location, routes, basename, allRoutes, 'navigation');
926
+ patchSpanEnd(navigationSpan, location, routes, basename, 'navigation');
812
927
  } else {
813
928
  // If no span was created, remove the placeholder
814
929
  activeNavigationSpans.delete(client);
@@ -875,8 +990,13 @@ function updatePageloadTransaction({
875
990
  activeRootSpan.setAttribute(core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source);
876
991
 
877
992
  // Patch span.end() to ensure we update the name one last time before the span is sent
878
- patchSpanEnd(activeRootSpan, location, routes, basename, allRoutes, 'pageload');
993
+ patchSpanEnd(activeRootSpan, location, routes, basename, 'pageload');
879
994
  }
995
+ } else if (activeRootSpan) {
996
+ // Even if branches is null (can happen when lazy routes haven't loaded yet),
997
+ // we still need to patch span.end() so that when lazy routes load and the span ends,
998
+ // we can update the transaction name correctly.
999
+ patchSpanEnd(activeRootSpan, location, routes, basename, 'pageload');
880
1000
  }
881
1001
  }
882
1002
 
@@ -971,7 +1091,6 @@ function patchSpanEnd(
971
1091
  location,
972
1092
  routes,
973
1093
  basename,
974
- _allRoutes,
975
1094
  spanType,
976
1095
  ) {
977
1096
  const patchedPropertyName = `__sentry_${spanType}_end_patched__` ;
@@ -981,8 +1100,7 @@ function patchSpanEnd(
981
1100
  return;
982
1101
  }
983
1102
 
984
- // Use the passed route context, or fall back to global Set
985
- const allRoutesSet = _allRoutes ? new Set(_allRoutes) : allRoutes;
1103
+ // Uses global allRoutes to access lazy-loaded routes added after this function was called.
986
1104
 
987
1105
  const originalEnd = span.end.bind(span);
988
1106
  let endCalled = false;
@@ -1013,29 +1131,40 @@ function patchSpanEnd(
1013
1131
  };
1014
1132
 
1015
1133
  const pendingPromises = pendingLazyRouteLoads.get(span);
1134
+ const mayHaveLazyRoutes = (span ).__sentry_may_have_lazy_routes__;
1135
+
1016
1136
  // Wait for lazy routes if:
1017
- // 1. There are pending promises AND
1137
+ // 1. (There are pending promises OR the span was marked as potentially having lazy routes) AND
1018
1138
  // 2. Current name exists AND
1019
1139
  // 3. Either the name has a wildcard OR the source is not 'route' (URL-based names)
1140
+ const hasPendingOrMayHaveLazyRoutes = (pendingPromises && pendingPromises.size > 0) || mayHaveLazyRoutes;
1020
1141
  const shouldWaitForLazyRoutes =
1021
- pendingPromises &&
1022
- pendingPromises.size > 0 &&
1142
+ hasPendingOrMayHaveLazyRoutes &&
1023
1143
  currentName &&
1024
1144
  (utils.transactionNameHasWildcard(currentName) || currentSource !== 'route');
1025
1145
 
1026
1146
  if (shouldWaitForLazyRoutes) {
1027
1147
  if (_lazyRouteTimeout === 0) {
1028
- tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutesSet);
1148
+ tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutes);
1029
1149
  cleanupNavigationSpan();
1030
1150
  originalEnd(endTimestamp);
1031
1151
  return;
1032
1152
  }
1033
1153
 
1034
- const allSettled = Promise.allSettled(pendingPromises).then(() => {});
1035
- const waitPromise =
1036
- _lazyRouteTimeout === Infinity
1037
- ? allSettled
1038
- : Promise.race([allSettled, new Promise(r => setTimeout(r, _lazyRouteTimeout))]);
1154
+ // If we have pending promises, wait for them. Otherwise, just wait for the timeout.
1155
+ // This handles the case where we know lazy routes might load but patchRoutesOnNavigation
1156
+ // hasn't been called yet.
1157
+ const timeoutPromise = new Promise(r => setTimeout(r, _lazyRouteTimeout));
1158
+ let waitPromise;
1159
+
1160
+ if (pendingPromises && pendingPromises.size > 0) {
1161
+ const allSettled = Promise.allSettled(pendingPromises).then(() => {});
1162
+ waitPromise = _lazyRouteTimeout === Infinity ? allSettled : Promise.race([allSettled, timeoutPromise]);
1163
+ } else {
1164
+ // No pending promises yet, but we know lazy routes might load
1165
+ // Wait for the timeout to give React Router time to call patchRoutesOnNavigation
1166
+ waitPromise = timeoutPromise;
1167
+ }
1039
1168
 
1040
1169
  waitPromise
1041
1170
  .then(() => {
@@ -1048,7 +1177,7 @@ function patchSpanEnd(
1048
1177
  routes,
1049
1178
  basename,
1050
1179
  spanType,
1051
- allRoutesSet,
1180
+ allRoutes,
1052
1181
  );
1053
1182
  cleanupNavigationSpan();
1054
1183
  originalEnd(endTimestamp);
@@ -1060,7 +1189,7 @@ function patchSpanEnd(
1060
1189
  return;
1061
1190
  }
1062
1191
 
1063
- tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutesSet);
1192
+ tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutes);
1064
1193
  cleanupNavigationSpan();
1065
1194
  originalEnd(endTimestamp);
1066
1195
  };