Skip to content

feat(android-nav3): [Android Nav3 2] Model navigation routes - #6130

Merged
0xadam-brown merged 5 commits into
feat/sentry-nav3-effect-stackfrom
feat/sentry-nav3-effect-2-routes
Sep 24, 2026
Merged

0xadam-brown merged 5 commits into
feat/sentry-nav3-effect-stackfrom
feat/sentry-nav3-effect-2-routes

Conversation

@0xadam-brown

@0xadam-brown 0xadam-brown commented Sep 18, 2026 •

Copy link
Copy Markdown
Member

PR Stack (Android Nav3)


📜 Description

To support Nav3 we have to map a host app's back stack to an internal representation suitable for the Sentry data we emit. This PR introduces the core logic for doing so in the form of a RouteTranslator.

Note that the RouteResolvers passed to the translators constructor are defined by the host app, and so we're careful to protect against misuse / unintended performance issues.

💡 Motivation and Context

addresses: JAVA-274

💚 How did you test it?

  • Unit tests
  • Manually via the (forthcoming) Nav3 sample app, including performance tests and macrobenchmarks

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

Build the observer layer that consumes these routes and updates Sentry state.

#skip-changelog

⚠️ Merge this PR using a merge commit (not squash). Later PRs in the stack are based on this branch.

@github-actions

github-actions Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 3cead78

@sentry

sentry Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.57.0 (1) release

⚙️ sentry-android Build Distribution Settings

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

@0xadam-brown
0xadam-brown force-pushed the feat/sentry-nav3-effect-1-module branch from e5d13ee to 1b98b50 Compare September 18, 2026 11:28
@0xadam-brown
0xadam-brown force-pushed the feat/sentry-nav3-effect-2-routes branch 2 times, most recently from dc5546c to b0eb957 Compare September 18, 2026 12:38
* Doing so prevents route names from being obfuscated while leaving per-route arguments to
* [RouteArgumentsExtractor].
*/
@ApiStatus.Experimental

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marked as experimental b/c this will be made public in a follow-on to the current PR stack. (Same below.)

@0xadam-brown 0xadam-brown added the deep-dive PR needs a thorough review of design, behavior, and edge cases label Sep 18, 2026

@runningcode runningcode left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before I give it a deeper look or maybe we can answer these in our session later, since I'm not a compose expert, what's the threading behavior on this? are these always called from the main thread since this is UI stuff?

One more question is that I wonder if it is safe to call the logger from inside the catch clause. I know we've had situations in the past where this was unsafe due to the SO/recursion risk.
The issue is that the logger also has user callbacks in the form of BeforeSendLogCallback and is therefore unsafe in the same way that the user callbacks are.

Comment thread sentry-android-navigation3/build.gradle.kts

@markushi markushi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, left two minor commments.

Base automatically changed from feat/sentry-nav3-effect-1-module to feat/sentry-nav3-effect-stack September 24, 2026 08:06
@0xadam-brown
0xadam-brown force-pushed the feat/sentry-nav3-effect-2-routes branch from b0eb957 to 4038ff4 Compare September 24, 2026 08:10

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread sentry/src/main/java/io/sentry/util/HttpUtils.java Outdated
Introduce the route translation layer for Navigation 3 so later stages can reason about route names and sanitized arguments in one place. At this stage the module still exposes no meaningful public API surface.
@0xadam-brown
0xadam-brown force-pushed the feat/sentry-nav3-effect-2-routes branch from 4038ff4 to 01c0ad0 Compare September 24, 2026 08:18
0xadam-brown and others added 3 commits September 24, 2026 10:44
Convert the new Navigation 3 route test assertions from kotlin.test to Google Truth to match the repository's preferred unit-test assertion style.

Co-Authored-By: OpenAI GPT-5.4 <noreply@openai.com>
Add a RetentionPolicy enum to RouteTranslator.translate so callers can declare whether route info for the lower or higher values in the provided list should be retained when an extraction budget is reached. dThis removes the implicit newest-first coupling while preserving the existing shared argument budget behavior for the top of the stack.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 16726da. Configure here.

@0xadam-brown

0xadam-brown commented Sep 24, 2026 •

Copy link
Copy Markdown
Member Author

what's the threading behavior on this? are these always called from the main thread since this is UI stuff?

Both RouteTranslator.translate() and the host app-provided extractors will be called on Compose's *Effect thread. On Android, that's the UI thread in practice.

We could in theory do the route translation work on a background thread (eg, by using a properly dispatched LaunchedEffect to call BackStackObserver in SentryNavEffect), but it'd be best to avoid b/c:

  • route and argument extractors shouldn't do much work (we cap the amount here and warn folks in the relevant APIs against it; and in almost all cases there's no good reason to do so); and
  • extracting on a background thread could cause state coordination issues for host apps, as they'd have to be careful about how they capture state in the extraction lambdas they pass to us.

(I've added a "Threading policy" section to the class KDoc.)

One more question is that I wonder if it is safe to call the logger from inside the catch clause. I know we've had situations in the past where this was unsafe due to the SO/recursion risk. The issue is that the logger also has user callbacks in the form of BeforeSendLogCallback and is therefore unsafe in the same way that the user callbacks are.

Great question, but I'm not worried in our case. BeforeSendLogCallback is only used with Sentry.logger(): ILoggerApi which wraps user logs in SentryLogEvents and ships them to our backend (ie, converts them into telemetry events).

All the logs here use SentryOptions.getLogger(): ILogger, which is a side-channel logger and avoids all of our transport processing paths. So it's much safer. Developers could in theory provide an ILogger implementation that throws when we try to log to it, but that'd be very unusual. And we're double-protected in that ILogger no-ops unless the host app calls SentryOptions.setDebug(true). (The basic idea being that ILogger is meant as a debugging tool for host app devs when they suspect the Sentry SDK is doing something fishy, and not as something that's left perpetually enabled.)

@0xadam-brown
0xadam-brown merged commit 5c8bd0a into feat/sentry-nav3-effect-stack Sep 24, 2026
74 of 79 checks passed
@0xadam-brown
0xadam-brown deleted the feat/sentry-nav3-effect-2-routes branch September 24, 2026 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deep-dive PR needs a thorough review of design, behavior, and edge cases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants