Skip to content

Commit ce6d964

Browse files
0xadam-browncodex
andcommitted
fix(android-nav3): Ignore no-op nav transactions
Treat no-op transactions from scopes.startTransaction as 'not started' in BackStackObserver. This prevents ignored or incompatible nav transactions from being bound to the default scope, which could otherwise leave a finished no-op transaction attached and block later real transactions until the next top-of-stack change. Add a regression test proving the observer leaves scope.transaction unset when startTransaction returns NoOpTransaction. Co-Authored-By: OpenAI GPT-5.4 <noreply@openai.com>
1 parent 67c8ed4 commit ce6d964

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

‎sentry-android-navigation3/src/main/kotlin/io/sentry/compose/navigation3/BackStackObserver.kt‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,10 @@ private class NavTransaction(private val scopes: IScopes) {
326326
transactionOptions,
327327
)
328328

329+
if (transaction.isNoOp) {
330+
return null
331+
}
332+
329333
activeNavTransaction = transaction
330334

331335
transaction.apply {

‎sentry-android-navigation3/src/test/kotlin/io/sentry/compose/navigation3/BackStackObserverTest.kt‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import io.sentry.IScope
88
import io.sentry.IScopes
99
import io.sentry.ISpan
1010
import io.sentry.ITransaction
11+
import io.sentry.NoOpTransaction
1112
import io.sentry.Scope
1213
import io.sentry.ScopeCallback
1314
import io.sentry.SentryOptions
@@ -574,6 +575,20 @@ class BackStackObserverTest {
574575
assertThat(fixture.scope.transaction).isSameInstanceAs(fixture.startedTransactions.single())
575576
}
576577

578+
@Test
579+
fun `onBackStackChanged does not bind a no-op nav transaction to the scope`() {
580+
val fixture = Fixture()
581+
whenever(fixture.scopes.startTransaction(any<TransactionContext>(), any<TransactionOptions>()))
582+
.thenReturn(NoOpTransaction.getInstance())
583+
val sut = fixture.getSut(config = ObserverConfig(enableNavigationTransactions = true))
584+
585+
sut.onBackStackChanged(listOf(HomeRoute()))
586+
587+
assertThat(fixture.startedTransactions).isEmpty()
588+
assertThat(fixture.scope.transaction).isNull()
589+
assertThat(fixture.scope.screen).isEqualTo("/HomeRoute")
590+
}
591+
577592
@Test
578593
fun `onBackStackChanged clears tracked scope state when the back stack becomes empty`() {
579594
val fixture = Fixture()

0 commit comments

Comments
 (0)