Skip to content
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

Fix: SentryTransaction#finish should not clear another transaction from the scope #1278

Merged
merged 2 commits into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* Enchancement: Integration interface better compatibility with Kotlin null-safety
* Enchancement: Simplify Sentry configuration in Spring integration (#1259)
* Enchancement: Optimize SentryTracingFilter when hub is disabled.
* Fix: SentryTransaction#finish should not clear another transaction from the scope (#1278)

Breaking Changes:
* Enchancement: SentryExceptionResolver should not send handled errors by default (#1248).
Expand Down
5 changes: 4 additions & 1 deletion sentry/src/main/java/io/sentry/Hub.java
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,10 @@ public void flush(long timeoutMillis) {
e);
} finally {
if (item != null) {
item.getScope().clearTransaction();
final Scope scope = item.getScope();
if (scope.getTransaction() == transaction) {
scope.clearTransaction();
Comment on lines +560 to +561
Copy link
Member

Choose a reason for hiding this comment

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

On Android where the scope is shared this would race since in between another transaction could have been set.

Another approach would be:

scope.clear(transaction)
And internal conditional atomic reference swap (i.e: https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.compareexchange?view=net-5.0)

}
}
}
}
Expand Down
24 changes: 22 additions & 2 deletions sentry/src/test/java/io/sentry/HubTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1028,18 +1028,38 @@ class HubTest {
}

@Test
fun `when captureTransaction, scope transaction is cleared`() {
fun `when transaction is set on scope, captureTransaction clears it from the scope`() {
val options = SentryOptions()
options.cacheDirPath = file.absolutePath
options.dsn = "https://[email protected]/proj"
options.setSerializer(mock())
val sut = Hub(options)

sut.captureTransaction(SentryTransaction("name", "op"), null)
val transaction = SentryTransaction(TransactionContext("name", "op", true), sut)
sut.configureScope { it.setTransaction(transaction) }
sut.captureTransaction(transaction, null)
sut.configureScope {
assertNull(it.transaction)
}
}

@Test
fun `when different transaction is set on scope, captureTransaction does not clear it from the scope`() {
val options = SentryOptions()
options.cacheDirPath = file.absolutePath
options.dsn = "https://[email protected]/proj"
options.setSerializer(mock())
val sut = Hub(options)

val transaction = SentryTransaction(TransactionContext("name", "op", true), sut)
val anotherTransaction = SentryTransaction(TransactionContext("name", "op", true), sut)
sut.configureScope { it.setTransaction(anotherTransaction) }
sut.captureTransaction(transaction, null)
sut.configureScope {
assertNotNull(it.transaction)
assertEquals(anotherTransaction, it.transaction)
}
}
//endregion

//region startTransaction tests
Expand Down