Skip to content

Commit 101f707

Browse files
authored
Do not send session updates for terminated sessions (#2849)
1 parent 0bff5c1 commit 101f707

File tree

5 files changed

+50
-4
lines changed

5 files changed

+50
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Deduplicate events happening in multiple threads simultaneously (e.g. `OutOfMemoryError`) ([#2845](https://github.com/getsentry/sentry-java/pull/2845))
88
- This will improve Crash-Free Session Rate as we no longer will send multiple Session updates with `Crashed` status, but only the one that is relevant
99
- Ensure no Java 8 method reference sugar is used for Android ([#2857](https://github.com/getsentry/sentry-java/pull/2857))
10+
- Do not send session updates for terminated sessions ([#2849](https://github.com/getsentry/sentry-java/pull/2849))
1011

1112
## 6.26.0
1213

sentry/api/sentry.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,6 +2063,7 @@ public final class io/sentry/Session : io/sentry/JsonSerializable, io/sentry/Jso
20632063
public fun getTimestamp ()Ljava/util/Date;
20642064
public fun getUnknown ()Ljava/util/Map;
20652065
public fun getUserAgent ()Ljava/lang/String;
2066+
public fun isTerminated ()Z
20662067
public fun serialize (Lio/sentry/ObjectWriter;Lio/sentry/ILogger;)V
20672068
public fun setInitAsTrue ()V
20682069
public fun setUnknown (Ljava/util/Map;)V

sentry/src/main/java/io/sentry/SentryClient.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,10 @@ private boolean shouldApplyScopeData(
137137
@Nullable Session session = null;
138138

139139
if (event != null) {
140-
session = updateSessionData(event, hint, scope);
140+
// https://develop.sentry.dev/sdk/sessions/#terminal-session-states
141+
if (sessionBeforeUpdate == null || !sessionBeforeUpdate.isTerminated()) {
142+
session = updateSessionData(event, hint, scope);
143+
}
141144

142145
if (!sample()) {
143146
options
@@ -490,9 +493,8 @@ Session updateSessionData(
490493
}
491494

492495
if (session.update(status, userAgent, crashedOrErrored, abnormalMechanism)) {
493-
// if we have an uncaughtExceptionHint we can end the session.
494-
if (HintUtils.hasType(
495-
hint, UncaughtExceptionHandlerIntegration.UncaughtExceptionHint.class)) {
496+
// if session terminated we can end it.
497+
if (session.isTerminated()) {
496498
session.end();
497499
}
498500
}

sentry/src/main/java/io/sentry/Session.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ public Session(
125125
null);
126126
}
127127

128+
public boolean isTerminated() {
129+
return status != State.Ok;
130+
}
131+
128132
@SuppressWarnings({"JdkObsolete", "JavaUtilDate"})
129133
public @Nullable Date getStarted() {
130134
if (started == null) {

sentry/src/test/java/io/sentry/SentryClientTest.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.sentry
22

33
import io.sentry.Scope.IWithPropagationContext
4+
import io.sentry.Session.State.Crashed
45
import io.sentry.clientreport.ClientReportTestHelper.Companion.assertClientReport
56
import io.sentry.clientreport.DiscardReason
67
import io.sentry.clientreport.DiscardedEvent
@@ -953,6 +954,21 @@ class SentryClientTest {
953954
}
954955
}
955956

957+
@Test
958+
fun `When event is non handled, end the session`() {
959+
val scope = Scope(fixture.sentryOptions)
960+
scope.startSession()
961+
962+
val event = SentryEvent().apply {
963+
exceptions = createNonHandledException()
964+
}
965+
fixture.getSut().updateSessionData(event, Hint(), scope)
966+
scope.withSession {
967+
assertEquals(Session.State.Crashed, it!!.status)
968+
assertNotNull(it.duration)
969+
}
970+
}
971+
956972
@Test
957973
fun `When event is handled, keep level as it is`() {
958974
val scope = Scope(fixture.sentryOptions)
@@ -1137,6 +1153,28 @@ class SentryClientTest {
11371153
}
11381154
}
11391155

1156+
@Test
1157+
fun `when session is in terminal state, does not send session update`() {
1158+
val sut = fixture.getSut()
1159+
1160+
val event = SentryEvent().apply {
1161+
exceptions = createNonHandledException()
1162+
}
1163+
val scope = Scope(fixture.sentryOptions)
1164+
val sessionPair = scope.startSession()
1165+
scope.withSession { it!!.update(Crashed, null, false) }
1166+
1167+
assertNotNull(sessionPair) {
1168+
sut.captureEvent(event, scope, null)
1169+
verify(fixture.transport).send(
1170+
check {
1171+
assertNull(it.items.find { item -> item.header.type == SentryItemType.Session })
1172+
},
1173+
anyOrNull()
1174+
)
1175+
}
1176+
}
1177+
11401178
@Test
11411179
fun `when contexts property is set on the event, property from scope contexts is not applied`() {
11421180
val sut = fixture.getSut()

0 commit comments

Comments
 (0)