-
-
Notifications
You must be signed in to change notification settings - Fork 360
feat(core): Name navigation spans using dispatched action payload #5982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
77aadad
3ca05a5
dcfe90c
d39dbda
461ba9b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -198,6 +198,7 @@ export const reactNavigationIntegration = ({ | |
| let latestRoute: NavigationRoute | undefined; | ||
|
|
||
| let latestNavigationSpan: Span | undefined; | ||
| let latestNavigationSpanNameCustomized: boolean = false; | ||
| let navigationProcessingSpan: Span | undefined; | ||
|
|
||
| let initialStateHandled: boolean = false; | ||
|
|
@@ -376,31 +377,40 @@ export const reactNavigationIntegration = ({ | |
| return; | ||
| } | ||
|
|
||
| // Extract route name from dispatch action payload when available | ||
| const dispatchedRouteName = useDispatchedActionData ? getRouteNameFromAction(event) : undefined; | ||
| if (useDispatchedActionData && event && !dispatchedRouteName && !isAppRestart) { | ||
| debug.log(`${INTEGRATION_NAME} Navigation action has no route name in payload, not starting navigation span.`); | ||
| return; | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dead
|
||
|
|
||
| if (latestNavigationSpan) { | ||
| debug.log(`${INTEGRATION_NAME} A transaction was detected that turned out to be a noop, discarding.`); | ||
| _discardLatestTransaction(); | ||
| clearStateChangeTimeout(); | ||
| } | ||
|
|
||
| latestNavigationSpan = startGenericIdleNavigationSpan( | ||
| tracing?.options.beforeStartSpan | ||
| ? tracing.options.beforeStartSpan(getDefaultIdleNavigationSpanOptions()) | ||
| : getDefaultIdleNavigationSpanOptions(), | ||
| { ...idleSpanOptions, isAppRestart }, | ||
| ); | ||
| const spanOptions = getDefaultIdleNavigationSpanOptions(); | ||
| if (dispatchedRouteName) { | ||
| spanOptions.name = dispatchedRouteName; | ||
sentry[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| const originalName = spanOptions.name; | ||
| const finalSpanOptions = tracing?.options.beforeStartSpan | ||
| ? tracing.options.beforeStartSpan(spanOptions) | ||
| : spanOptions; | ||
| latestNavigationSpanNameCustomized = finalSpanOptions.name !== originalName; | ||
|
|
||
| latestNavigationSpan = startGenericIdleNavigationSpan(finalSpanOptions, { ...idleSpanOptions, isAppRestart }); | ||
| latestNavigationSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_ORIGIN_AUTO_NAVIGATION_REACT_NAVIGATION); | ||
| latestNavigationSpan?.setAttribute(SEMANTIC_ATTRIBUTE_NAVIGATION_ACTION_TYPE, navigationActionType); | ||
| if (ignoreEmptyBackNavigationTransactions) { | ||
| ignoreEmptyBackNavigation(getClient(), latestNavigationSpan); | ||
| } | ||
| // Always discard transactions that never receive route information | ||
| const spanToCheck = latestNavigationSpan; | ||
| ignoreEmptyRouteChangeTransactions( | ||
| getClient(), | ||
| spanToCheck, | ||
| DEFAULT_NAVIGATION_SPAN_NAME, | ||
| () => latestNavigationSpan === spanToCheck, | ||
| ); | ||
| const spanName = finalSpanOptions.name ?? DEFAULT_NAVIGATION_SPAN_NAME; | ||
| ignoreEmptyRouteChangeTransactions(getClient(), spanToCheck, spanName, () => latestNavigationSpan === spanToCheck); | ||
|
|
||
| if (enableTimeToInitialDisplay && latestNavigationSpan) { | ||
| NATIVE.setActiveSpanId(latestNavigationSpan.spanContext().spanId); | ||
|
|
@@ -472,7 +482,7 @@ export const reactNavigationIntegration = ({ | |
| navigationProcessingSpan?.end(stateChangedTimestamp); | ||
| navigationProcessingSpan = undefined; | ||
|
|
||
| if (spanToJSON(latestNavigationSpan).description === DEFAULT_NAVIGATION_SPAN_NAME) { | ||
| if (!latestNavigationSpanNameCustomized) { | ||
| latestNavigationSpan.updateName(routeName); | ||
| } | ||
| const sendDefaultPii = getClient()?.getOptions()?.sendDefaultPii ?? false; | ||
|
|
@@ -578,6 +588,20 @@ interface NavigationContainer { | |
| getState: () => NavigationState | undefined; | ||
| } | ||
|
|
||
| /** | ||
| * Extracts the route name from a React Navigation dispatch action payload. | ||
| * | ||
| * Actions like NAVIGATE, PUSH, REPLACE, JUMP_TO carry the target route name | ||
| * in `action.payload.name`. Actions like GO_BACK, POP, POP_TO_TOP do not. | ||
| */ | ||
| function getRouteNameFromAction(event: UnsafeAction | undefined): string | undefined { | ||
| const payload = event?.data?.action?.payload; | ||
| if (payload && typeof payload === 'object' && 'name' in payload && typeof payload.name === 'string') { | ||
| return payload.name; | ||
| } | ||
| return undefined; | ||
| } | ||
|
|
||
| /** | ||
| * Returns React Navigation integration of the given client. | ||
| */ | ||
|
|
||


Uh oh!
There was an error while loading. Please reload this page.