Skip to content

Commit e4920d4

Browse files
committed
Address review comments
1 parent 1c30c54 commit e4920d4

File tree

2 files changed

+58
-53
lines changed

2 files changed

+58
-53
lines changed

dev-packages/e2e-tests/test-applications/react-router-7-lazy-routes/tests/transactions.test.ts

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ test('Updates navigation transaction name correctly when span is cancelled early
502502
test('Creates separate transactions for rapid consecutive navigations', async ({ page }) => {
503503
await page.goto('/');
504504

505-
// First navigation: / -> /lazy/inner/:id/:anotherId/:someAnotherId
505+
// Set up transaction listeners
506506
const firstTransactionPromise = waitForTransaction('react-router-7-lazy-routes', async transactionEvent => {
507507
return (
508508
!!transactionEvent?.transaction &&
@@ -511,19 +511,6 @@ test('Creates separate transactions for rapid consecutive navigations', async ({
511511
);
512512
});
513513

514-
const navigationToInner = page.locator('id=navigation');
515-
await expect(navigationToInner).toBeVisible();
516-
await navigationToInner.click();
517-
518-
const firstEvent = await firstTransactionPromise;
519-
520-
// Verify first transaction
521-
expect(firstEvent.transaction).toBe('/lazy/inner/:id/:anotherId/:someAnotherId');
522-
expect(firstEvent.contexts?.trace?.op).toBe('navigation');
523-
const firstTraceId = firstEvent.contexts?.trace?.trace_id;
524-
const firstSpanId = firstEvent.contexts?.trace?.span_id;
525-
526-
// Second navigation: /lazy/inner -> /another-lazy/sub/:id/:subId
527514
const secondTransactionPromise = waitForTransaction('react-router-7-lazy-routes', async transactionEvent => {
528515
return (
529516
!!transactionEvent?.transaction &&
@@ -532,35 +519,47 @@ test('Creates separate transactions for rapid consecutive navigations', async ({
532519
);
533520
});
534521

535-
const navigationToAnother = page.locator('id=navigate-to-another-from-inner');
536-
await expect(navigationToAnother).toBeVisible();
537-
await navigationToAnother.click();
522+
// Third navigation promise - using counter to match second occurrence of same route
523+
let innerRouteMatchCount = 0;
524+
const thirdTransactionPromise = waitForTransaction('react-router-7-lazy-routes', async transactionEvent => {
525+
if (
526+
transactionEvent?.transaction &&
527+
transactionEvent.contexts?.trace?.op === 'navigation' &&
528+
transactionEvent.transaction === '/lazy/inner/:id/:anotherId/:someAnotherId'
529+
) {
530+
innerRouteMatchCount++;
531+
return innerRouteMatchCount === 2; // Match the second occurrence
532+
}
533+
return false;
534+
});
535+
536+
// Perform navigations
537+
// First navigation: / -> /lazy/inner/:id/:anotherId/:someAnotherId
538+
await page.locator('id=navigation').click();
539+
540+
const firstEvent = await firstTransactionPromise;
541+
542+
// Second navigation: /lazy/inner -> /another-lazy/sub/:id/:subId
543+
await page.locator('id=navigate-to-another-from-inner').click();
538544

539545
const secondEvent = await secondTransactionPromise;
540546

541-
// Verify second transaction
547+
// Third navigation: /another-lazy -> /lazy/inner/:id/:anotherId/:someAnotherId (back to same route as first)
548+
await page.locator('id=navigate-to-inner-from-deep').click();
549+
550+
const thirdEvent = await thirdTransactionPromise;
551+
552+
// Verify transactions
553+
expect(firstEvent.transaction).toBe('/lazy/inner/:id/:anotherId/:someAnotherId');
554+
expect(firstEvent.contexts?.trace?.op).toBe('navigation');
555+
const firstTraceId = firstEvent.contexts?.trace?.trace_id;
556+
const firstSpanId = firstEvent.contexts?.trace?.span_id;
557+
542558
expect(secondEvent.transaction).toBe('/another-lazy/sub/:id/:subId');
543559
expect(secondEvent.contexts?.trace?.op).toBe('navigation');
544560
const secondTraceId = secondEvent.contexts?.trace?.trace_id;
545561
const secondSpanId = secondEvent.contexts?.trace?.span_id;
546562

547-
// Third navigation: /another-lazy -> /lazy/inner/:id/:anotherId/:someAnotherId (back to same route as first)
548-
const thirdTransactionPromise = waitForTransaction('react-router-7-lazy-routes', async transactionEvent => {
549-
return (
550-
!!transactionEvent?.transaction &&
551-
transactionEvent.contexts?.trace?.op === 'navigation' &&
552-
transactionEvent.transaction === '/lazy/inner/:id/:anotherId/:someAnotherId' &&
553-
// Ensure we're not matching the first transaction again
554-
transactionEvent.contexts?.trace?.trace_id !== firstTraceId
555-
);
556-
});
557-
558-
const navigationBackToInner = page.locator('id=navigate-to-inner-from-deep');
559-
await expect(navigationBackToInner).toBeVisible();
560-
await navigationBackToInner.click();
561-
562-
const thirdEvent = await thirdTransactionPromise;
563-
564563
// Verify third transaction
565564
expect(thirdEvent.transaction).toBe('/lazy/inner/:id/:anotherId/:someAnotherId');
566565
expect(thirdEvent.contexts?.trace?.op).toBe('navigation');

packages/react/src/reactrouter-compat-utils/instrumentation.tsx

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,26 @@ export function addResolvedRoutesToParent(resolvedRoutes: RouteObject[], parentR
7676
}
7777
}
7878

79+
/**
80+
* Determines if a navigation should be handled based on router state.
81+
* Only handles:
82+
* - PUSH navigations (always)
83+
* - POP navigations (only after initial pageload is complete)
84+
* - When router state is 'idle' (not 'loading' or 'submitting')
85+
*
86+
* During 'loading' or 'submitting', state.location may still have the old pathname,
87+
* which would cause us to create a span for the wrong route.
88+
*/
89+
function shouldHandleNavigation(
90+
state: { historyAction: string; navigation: { state: string } },
91+
isInitialPageloadComplete: boolean,
92+
): boolean {
93+
return (
94+
(state.historyAction === 'PUSH' || (state.historyAction === 'POP' && isInitialPageloadComplete)) &&
95+
state.navigation.state === 'idle'
96+
);
97+
}
98+
7999
export interface ReactRouterOptions {
80100
useEffect: UseEffect;
81101
useLocation: UseLocation;
@@ -277,14 +297,7 @@ export function createV6CompatibleWrapCreateBrowserRouter<
277297
// If we haven't seen a pageload span yet, keep waiting (don't mark as complete)
278298
}
279299

280-
// Only handle navigation when it's complete (state is idle).
281-
// During 'loading' or 'submitting', state.location may still have the old pathname,
282-
// which would cause us to create a span for the wrong route.
283-
const shouldHandleNavigation =
284-
(state.historyAction === 'PUSH' || (state.historyAction === 'POP' && isInitialPageloadComplete)) &&
285-
state.navigation.state === 'idle';
286-
287-
if (shouldHandleNavigation) {
300+
if (shouldHandleNavigation(state, isInitialPageloadComplete)) {
288301
handleNavigation({
289302
location: state.location,
290303
routes,
@@ -401,14 +414,7 @@ export function createV6CompatibleWrapCreateMemoryRouter<
401414
// If we haven't seen a pageload span yet, keep waiting (don't mark as complete)
402415
}
403416

404-
// Only handle navigation when it's complete (state is idle).
405-
// During 'loading' or 'submitting', state.location may still have the old pathname,
406-
// which would cause us to create a span for the wrong route.
407-
const shouldHandleNavigation =
408-
(state.historyAction === 'PUSH' || (state.historyAction === 'POP' && isInitialPageloadComplete)) &&
409-
state.navigation.state === 'idle';
410-
411-
if (shouldHandleNavigation) {
417+
if (shouldHandleNavigation(state, isInitialPageloadComplete)) {
412418
handleNavigation({
413419
location: state.location,
414420
routes,
@@ -622,8 +628,8 @@ function tryUpdateSpanName(
622628
newName: string,
623629
newSource: string,
624630
): void {
625-
const isNewNameBetter = newName !== currentSpanName && newName.includes(':');
626-
if (isNewNameBetter) {
631+
const isNewNameParameterized = newName !== currentSpanName && newName.includes(':');
632+
if (isNewNameParameterized) {
627633
activeSpan.updateName(newName);
628634
activeSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, newSource as 'route' | 'url' | 'custom');
629635
}

0 commit comments

Comments
 (0)