Skip to content

Commit 6ce1197

Browse files
authored
Avoid multiple breadcrumbs from OkHttpEventListener (#3175)
* increased SentryOkHttpEvent.scheduleFinish timeout 500ms -> 800ms * added a guard to avoid finishing an already finished OkHttpEvent
1 parent 37dd784 commit 6ce1197

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
### Fixes
1919

20+
- Avoid multiple breadcrumbs from OkHttpEventListener ([#3175](https://github.com/getsentry/sentry-java/pull/3175))
2021
- Apply OkHttp listener auto finish timestamp to all running spans ([#3167](https://github.com/getsentry/sentry-java/pull/3167))
2122
- Fix not eligible for auto proxying warnings ([#3154](https://github.com/getsentry/sentry-java/pull/3154))
2223
- Set default fingerprint for ANRv2 events to correctly group background and foreground ANRs ([#3164](https://github.com/getsentry/sentry-java/pull/3164))

sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEvent.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean
2626

2727
private const val PROTOCOL_KEY = "protocol"
2828
private const val ERROR_MESSAGE_KEY = "error_message"
29-
private const val RESPONSE_BODY_TIMEOUT_MILLIS = 500L
29+
private const val RESPONSE_BODY_TIMEOUT_MILLIS = 800L
3030
internal const val TRACE_ORIGIN = "auto.http.okhttp"
3131

3232
@Suppress("TooManyFunctions")
@@ -37,6 +37,7 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req
3737
private var response: Response? = null
3838
private var clientErrorResponse: Response? = null
3939
private val isReadingResponseBody = AtomicBoolean(false)
40+
private val isEventFinished = AtomicBoolean(false)
4041

4142
init {
4243
val urlDetails = UrlUtils.parse(request.url.toString())
@@ -138,6 +139,10 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req
138139

139140
/** Finishes the call root span, and runs [beforeFinish] on it. Then a breadcrumb is sent. */
140141
fun finishEvent(finishDate: SentryDate? = null, beforeFinish: ((span: ISpan) -> Unit)? = null) {
142+
// If the event already finished, we don't do anything
143+
if (isEventFinished.getAndSet(true)) {
144+
return
145+
}
141146
// We put data in the hint and send a breadcrumb
142147
val hint = Hint()
143148
hint.set(TypeCheckHint.OKHTTP_REQUEST, request)

sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventTest.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import org.mockito.kotlin.eq
3737
import org.mockito.kotlin.mock
3838
import org.mockito.kotlin.never
3939
import org.mockito.kotlin.spy
40+
import org.mockito.kotlin.times
4041
import org.mockito.kotlin.verify
4142
import org.mockito.kotlin.whenever
4243
import java.util.concurrent.RejectedExecutionException
@@ -252,6 +253,14 @@ class SentryOkHttpEventTest {
252253
)
253254
}
254255

256+
@Test
257+
fun `when finishEvent multiple times, only one breadcrumb is captured`() {
258+
val sut = fixture.getSut()
259+
sut.finishEvent()
260+
sut.finishEvent()
261+
verify(fixture.hub, times(1)).addBreadcrumb(any<Breadcrumb>(), any())
262+
}
263+
255264
@Test
256265
fun `when finishEvent, does not override running spans status if set`() {
257266
val sut = fixture.getSut()

0 commit comments

Comments
 (0)