From 105211a6b3481fd774002f5ff15a9cb95069eb85 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Wed, 26 Aug 2026 11:32:44 +0200 Subject: [PATCH 1/3] fix(okhttp): keep the wrapped EventListener per Call Co-Authored-By: Claude Opus 5 --- sentry-okhttp/build.gradle.kts | 1 + .../okhttp/SentryOkHttpEventListener.kt | 115 +++++++++-------- ...SentryOkHttpEventListenerDelegationTest.kt | 122 ++++++++++++++++++ .../okhttp/SentryOkHttpEventListenerTest.kt | 16 ++- 4 files changed, 195 insertions(+), 59 deletions(-) create mode 100644 sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerDelegationTest.kt diff --git a/sentry-okhttp/build.gradle.kts b/sentry-okhttp/build.gradle.kts index 47b8bfe5b15..94575f54984 100644 --- a/sentry-okhttp/build.gradle.kts +++ b/sentry-okhttp/build.gradle.kts @@ -38,6 +38,7 @@ dependencies { testImplementation(libs.mockito.inline) testImplementation(libs.okhttp) testImplementation(libs.okhttp.mockwebserver) + testImplementation(libs.google.truth) } buildConfig { diff --git a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt index 8ef67b3bb17..b2362639a50 100644 --- a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt +++ b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt @@ -45,7 +45,7 @@ public open class SentryOkHttpEventListener( private val scopes: IScopes = ScopesAdapter.getInstance(), private val originalEventListenerCreator: ((call: Call) -> EventListener)? = null, ) : EventListener() { - private var originalEventListener: EventListener? = null + private val originalEventListenerMap: MutableMap = ConcurrentHashMap() public companion object { internal const val PROXY_SELECT_EVENT = "http.client.proxy_select_ms" @@ -85,18 +85,23 @@ public open class SentryOkHttpEventListener( ) : this(scopes, originalEventListenerCreator = { originalEventListenerFactory.create(it) }) override fun callStart(call: Call) { - originalEventListener = originalEventListenerCreator?.invoke(call) + // The EventListener.Factory contract binds a listener to a single call, so the wrapped + // listener is kept per call instead of in a field shared by all concurrent calls + val originalEventListener = originalEventListenerCreator?.invoke(call) + if (originalEventListener != null) { + originalEventListenerMap[call] = originalEventListener + } originalEventListener?.callStart(call) // If the wrapped EventListener is ours, we can just delegate the calls, // without creating other events that would create duplicates - if (canCreateEventSpan()) { + if (canCreateEventSpan(originalEventListener)) { eventMap[call] = SentryOkHttpEvent(scopes, call.request()) } } override fun proxySelectStart(call: Call, url: HttpUrl) { - originalEventListener?.proxySelectStart(call, url) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.proxySelectStart(call, url) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -104,8 +109,8 @@ public open class SentryOkHttpEventListener( } override fun proxySelectEnd(call: Call, url: HttpUrl, proxies: List) { - originalEventListener?.proxySelectEnd(call, url, proxies) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.proxySelectEnd(call, url, proxies) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -117,8 +122,8 @@ public open class SentryOkHttpEventListener( } override fun dnsStart(call: Call, domainName: String) { - originalEventListener?.dnsStart(call, domainName) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.dnsStart(call, domainName) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -126,8 +131,8 @@ public open class SentryOkHttpEventListener( } override fun dnsEnd(call: Call, domainName: String, inetAddressList: List) { - originalEventListener?.dnsEnd(call, domainName, inetAddressList) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.dnsEnd(call, domainName, inetAddressList) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -140,8 +145,8 @@ public open class SentryOkHttpEventListener( } override fun connectStart(call: Call, inetSocketAddress: InetSocketAddress, proxy: Proxy) { - originalEventListener?.connectStart(call, inetSocketAddress, proxy) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.connectStart(call, inetSocketAddress, proxy) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -149,8 +154,8 @@ public open class SentryOkHttpEventListener( } override fun secureConnectStart(call: Call) { - originalEventListener?.secureConnectStart(call) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.secureConnectStart(call) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -158,8 +163,8 @@ public open class SentryOkHttpEventListener( } override fun secureConnectEnd(call: Call, handshake: Handshake?) { - originalEventListener?.secureConnectEnd(call, handshake) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.secureConnectEnd(call, handshake) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -172,8 +177,8 @@ public open class SentryOkHttpEventListener( proxy: Proxy, protocol: Protocol?, ) { - originalEventListener?.connectEnd(call, inetSocketAddress, proxy, protocol) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.connectEnd(call, inetSocketAddress, proxy, protocol) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -188,8 +193,8 @@ public open class SentryOkHttpEventListener( protocol: Protocol?, ioe: IOException, ) { - originalEventListener?.connectFailed(call, inetSocketAddress, proxy, protocol, ioe) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.connectFailed(call, inetSocketAddress, proxy, protocol, ioe) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -202,8 +207,8 @@ public open class SentryOkHttpEventListener( } override fun connectionAcquired(call: Call, connection: Connection) { - originalEventListener?.connectionAcquired(call, connection) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.connectionAcquired(call, connection) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -211,8 +216,8 @@ public open class SentryOkHttpEventListener( } override fun connectionReleased(call: Call, connection: Connection) { - originalEventListener?.connectionReleased(call, connection) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.connectionReleased(call, connection) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -220,8 +225,8 @@ public open class SentryOkHttpEventListener( } override fun requestHeadersStart(call: Call) { - originalEventListener?.requestHeadersStart(call) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.requestHeadersStart(call) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -229,8 +234,8 @@ public open class SentryOkHttpEventListener( } override fun requestHeadersEnd(call: Call, request: Request) { - originalEventListener?.requestHeadersEnd(call, request) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.requestHeadersEnd(call, request) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -238,8 +243,8 @@ public open class SentryOkHttpEventListener( } override fun requestBodyStart(call: Call) { - originalEventListener?.requestBodyStart(call) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.requestBodyStart(call) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -247,8 +252,8 @@ public open class SentryOkHttpEventListener( } override fun requestBodyEnd(call: Call, byteCount: Long) { - originalEventListener?.requestBodyEnd(call, byteCount) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.requestBodyEnd(call, byteCount) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -261,8 +266,8 @@ public open class SentryOkHttpEventListener( } override fun requestFailed(call: Call, ioe: IOException) { - originalEventListener?.requestFailed(call, ioe) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.requestFailed(call, ioe) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -282,8 +287,8 @@ public open class SentryOkHttpEventListener( } override fun responseHeadersStart(call: Call) { - originalEventListener?.responseHeadersStart(call) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.responseHeadersStart(call) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -291,8 +296,8 @@ public open class SentryOkHttpEventListener( } override fun responseHeadersEnd(call: Call, response: Response) { - originalEventListener?.responseHeadersEnd(call, response) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.responseHeadersEnd(call, response) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -307,8 +312,8 @@ public open class SentryOkHttpEventListener( } override fun responseBodyStart(call: Call) { - originalEventListener?.responseBodyStart(call) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.responseBodyStart(call) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -316,8 +321,8 @@ public open class SentryOkHttpEventListener( } override fun responseBodyEnd(call: Call, byteCount: Long) { - originalEventListener?.responseBodyEnd(call, byteCount) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.responseBodyEnd(call, byteCount) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -330,8 +335,8 @@ public open class SentryOkHttpEventListener( } override fun responseFailed(call: Call, ioe: IOException) { - originalEventListener?.responseFailed(call, ioe) - if (!canCreateEventSpan()) { + originalEventListenerMap[call]?.responseFailed(call, ioe) + if (!canCreateEventSpan(call)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -351,14 +356,15 @@ public open class SentryOkHttpEventListener( } override fun callEnd(call: Call) { - originalEventListener?.callEnd(call) + originalEventListenerMap.remove(call)?.callEnd(call) val okHttpEvent: SentryOkHttpEvent = eventMap.remove(call) ?: return okHttpEvent.finish() } override fun callFailed(call: Call, ioe: IOException) { + val originalEventListener = originalEventListenerMap.remove(call) originalEventListener?.callFailed(call, ioe) - if (!canCreateEventSpan()) { + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap.remove(call) ?: return @@ -370,26 +376,29 @@ public open class SentryOkHttpEventListener( } override fun canceled(call: Call) { - originalEventListener?.canceled(call) + originalEventListenerMap[call]?.canceled(call) } override fun satisfactionFailure(call: Call, response: Response) { - originalEventListener?.satisfactionFailure(call, response) + originalEventListenerMap[call]?.satisfactionFailure(call, response) } override fun cacheHit(call: Call, response: Response) { - originalEventListener?.cacheHit(call, response) + originalEventListenerMap[call]?.cacheHit(call, response) } override fun cacheMiss(call: Call) { - originalEventListener?.cacheMiss(call) + originalEventListenerMap[call]?.cacheMiss(call) } override fun cacheConditionalHit(call: Call, cachedResponse: Response) { - originalEventListener?.cacheConditionalHit(call, cachedResponse) + originalEventListenerMap[call]?.cacheConditionalHit(call, cachedResponse) } - private fun canCreateEventSpan(): Boolean { + private fun canCreateEventSpan(call: Call): Boolean = + canCreateEventSpan(originalEventListenerMap[call]) + + private fun canCreateEventSpan(originalEventListener: EventListener?): Boolean { // If the wrapped EventListener is ours, we shouldn't create spans, as the originalEventListener // already did it // In case SentryOkHttpEventListener from sentry-android-okhttp is used, the is check won't work diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerDelegationTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerDelegationTest.kt new file mode 100644 index 00000000000..ee29322213a --- /dev/null +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerDelegationTest.kt @@ -0,0 +1,122 @@ +package io.sentry.okhttp + +import com.google.common.truth.Truth.assertThat +import io.sentry.IScopes +import io.sentry.SentryOptions +import java.io.IOException +import kotlin.test.Test +import okhttp3.Call +import okhttp3.EventListener +import okhttp3.OkHttpClient +import okhttp3.Request +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class SentryOkHttpEventListenerDelegationTest { + class RecordingListener(val ownCall: Call) : EventListener() { + val received = mutableListOf>() + + override fun callStart(call: Call) { + received += "callStart" to call + } + + override fun dnsStart(call: Call, domainName: String) { + received += "dnsStart" to call + } + + override fun callEnd(call: Call) { + received += "callEnd" to call + } + + override fun callFailed(call: Call, ioe: IOException) { + received += "callFailed" to call + } + + fun mismatches(): List> = received.filter { it.second !== ownCall } + } + + class Fixture { + val scopes = mock() + val client = OkHttpClient() + val listeners = mutableListOf() + + fun getSut(): SentryOkHttpEventListener { + whenever(scopes.options).thenReturn(SentryOptions()) + return SentryOkHttpEventListener( + scopes, + EventListener.Factory { call -> RecordingListener(call).also { listeners.add(it) } }, + ) + } + + fun newCall(path: String): Call = + client.newCall(Request.Builder().url("http://localhost/$path").build()) + } + + private val fixture = Fixture() + + @Test + fun `each call is delegated to the listener created for it`() { + val sut = fixture.getSut() + val call1 = fixture.newCall("1") + val call2 = fixture.newCall("2") + + sut.callStart(call1) + sut.callStart(call2) + sut.dnsStart(call1, "sentry.io") + sut.dnsStart(call2, "sentry.io") + sut.callEnd(call1) + sut.callEnd(call2) + + val (listener1, listener2) = fixture.listeners + assertThat(listener1.mismatches()).isEmpty() + assertThat(listener2.mismatches()).isEmpty() + assertThat(listener1.received.map { it.first }) + .containsExactly("callStart", "dnsStart", "callEnd") + .inOrder() + assertThat(listener2.received.map { it.first }) + .containsExactly("callStart", "dnsStart", "callEnd") + .inOrder() + } + + @Test + fun `callbacks without a preceding callStart are not delegated`() { + val sut = fixture.getSut() + val call1 = fixture.newCall("1") + val call2 = fixture.newCall("2") + + sut.callStart(call1) + sut.dnsStart(call2, "sentry.io") + sut.callEnd(call2) + + assertThat(fixture.listeners).hasSize(1) + assertThat(fixture.listeners.single().received.map { it.first }).containsExactly("callStart") + } + + @Test + fun `a finished call is no longer delegated to`() { + val sut = fixture.getSut() + val call = fixture.newCall("1") + + sut.callStart(call) + sut.callEnd(call) + sut.dnsStart(call, "sentry.io") + + assertThat(fixture.listeners.single().received.map { it.first }) + .containsExactly("callStart", "callEnd") + .inOrder() + } + + @Test + fun `a failed call is no longer delegated to`() { + val sut = fixture.getSut() + val call = fixture.newCall("1") + + sut.callStart(call) + sut.callFailed(call, IOException()) + sut.dnsStart(call, "sentry.io") + + assertThat(fixture.listeners.single().received.map { it.first }) + .containsExactly("callStart", "callFailed") + .inOrder() + } +} diff --git a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt index 3c4ebe0dae6..e4772145879 100644 --- a/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt +++ b/sentry-okhttp/src/test/java/io/sentry/okhttp/SentryOkHttpEventListenerTest.kt @@ -227,7 +227,7 @@ class SentryOkHttpEventListenerTest { val call = sut.newCall(request) val response = mock() whenever(response.protocol).thenReturn(Protocol.HTTP_1_1) - verifyDelegation(listener, fixture.mockEventListener, call, response) + verifyDelegation(listener, fixture.mockEventListener, call, sut.newCall(request), response) } @Test @@ -238,7 +238,7 @@ class SentryOkHttpEventListenerTest { val call = sut.newCall(request) val response = mock() whenever(response.protocol).thenReturn(Protocol.HTTP_1_1) - verifyDelegation(listener, fixture.mockEventListener, call, response) + verifyDelegation(listener, fixture.mockEventListener, call, sut.newCall(request), response) } @Test @@ -250,7 +250,7 @@ class SentryOkHttpEventListenerTest { val call = sut.newCall(request) val response = mock() whenever(response.protocol).thenReturn(Protocol.HTTP_1_1) - verifyDelegation(listener, originalListener, call, response) + verifyDelegation(listener, originalListener, call, sut.newCall(request), response) } @Test @@ -262,7 +262,7 @@ class SentryOkHttpEventListenerTest { val call = sut.newCall(request) val response = mock() whenever(response.protocol).thenReturn(Protocol.HTTP_1_1) - verifyDelegation(listener, originalListener, call, response) + verifyDelegation(listener, originalListener, call, sut.newCall(request), response) } @Test @@ -304,6 +304,7 @@ class SentryOkHttpEventListenerTest { listener: SentryOkHttpEventListener, originalListener: EventListener, call: Call, + failedCall: Call, response: Response, ) { listener.callStart(call) @@ -352,7 +353,10 @@ class SentryOkHttpEventListenerTest { verify(originalListener).responseFailed(eq(call), any()) listener.callEnd(call) verify(originalListener).callEnd(eq(call)) - listener.callFailed(call, mock()) - verify(originalListener).callFailed(eq(call), any()) + + // callEnd and callFailed are both terminal, so a failing call is a separate one + listener.callStart(failedCall) + listener.callFailed(failedCall, mock()) + verify(originalListener).callFailed(eq(failedCall), any()) } } From 14f6b504fc5701a114ad78761841dae9fcfecd51 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Wed, 26 Aug 2026 11:35:51 +0200 Subject: [PATCH 2/3] docs: add changelog entry Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 878238076f3..d31b5ab9d23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Prevent duplicated breadcrumbs on tombstone-merged native crash events ([#5888](https://github.com/getsentry/sentry-java/pull/5888)) - Prevent a class of Session Replay deadlocks by confining lifecycle state changes to Android's main thread ([#5965](https://github.com/getsentry/sentry-java/pull/5965)) - Symbolicate tombstone native frames for libraries loaded directly from APKs ([#5992](https://github.com/getsentry/sentry-java/pull/5992)) +- Keep the `EventListener` wrapped by `SentryOkHttpEventListener` per `Call` ([#6003](https://github.com/getsentry/sentry-java/pull/6003)) ### Features From 11786ec26721f97bc026d06b22d7fe2b7941e25d Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Wed, 26 Aug 2026 11:52:05 +0200 Subject: [PATCH 3/3] refactor(okhttp): look up the wrapped EventListener once per callback Co-Authored-By: Claude Opus 5 --- .../okhttp/SentryOkHttpEventListener.kt | 108 ++++++++++-------- 1 file changed, 63 insertions(+), 45 deletions(-) diff --git a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt index b2362639a50..5d2bf143e9e 100644 --- a/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt +++ b/sentry-okhttp/src/main/java/io/sentry/okhttp/SentryOkHttpEventListener.kt @@ -100,8 +100,9 @@ public open class SentryOkHttpEventListener( } override fun proxySelectStart(call: Call, url: HttpUrl) { - originalEventListenerMap[call]?.proxySelectStart(call, url) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.proxySelectStart(call, url) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -109,8 +110,9 @@ public open class SentryOkHttpEventListener( } override fun proxySelectEnd(call: Call, url: HttpUrl, proxies: List) { - originalEventListenerMap[call]?.proxySelectEnd(call, url, proxies) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.proxySelectEnd(call, url, proxies) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -122,8 +124,9 @@ public open class SentryOkHttpEventListener( } override fun dnsStart(call: Call, domainName: String) { - originalEventListenerMap[call]?.dnsStart(call, domainName) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.dnsStart(call, domainName) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -131,8 +134,9 @@ public open class SentryOkHttpEventListener( } override fun dnsEnd(call: Call, domainName: String, inetAddressList: List) { - originalEventListenerMap[call]?.dnsEnd(call, domainName, inetAddressList) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.dnsEnd(call, domainName, inetAddressList) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -145,8 +149,9 @@ public open class SentryOkHttpEventListener( } override fun connectStart(call: Call, inetSocketAddress: InetSocketAddress, proxy: Proxy) { - originalEventListenerMap[call]?.connectStart(call, inetSocketAddress, proxy) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.connectStart(call, inetSocketAddress, proxy) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -154,8 +159,9 @@ public open class SentryOkHttpEventListener( } override fun secureConnectStart(call: Call) { - originalEventListenerMap[call]?.secureConnectStart(call) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.secureConnectStart(call) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -163,8 +169,9 @@ public open class SentryOkHttpEventListener( } override fun secureConnectEnd(call: Call, handshake: Handshake?) { - originalEventListenerMap[call]?.secureConnectEnd(call, handshake) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.secureConnectEnd(call, handshake) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -177,8 +184,9 @@ public open class SentryOkHttpEventListener( proxy: Proxy, protocol: Protocol?, ) { - originalEventListenerMap[call]?.connectEnd(call, inetSocketAddress, proxy, protocol) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.connectEnd(call, inetSocketAddress, proxy, protocol) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -193,8 +201,9 @@ public open class SentryOkHttpEventListener( protocol: Protocol?, ioe: IOException, ) { - originalEventListenerMap[call]?.connectFailed(call, inetSocketAddress, proxy, protocol, ioe) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.connectFailed(call, inetSocketAddress, proxy, protocol, ioe) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -207,8 +216,9 @@ public open class SentryOkHttpEventListener( } override fun connectionAcquired(call: Call, connection: Connection) { - originalEventListenerMap[call]?.connectionAcquired(call, connection) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.connectionAcquired(call, connection) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -216,8 +226,9 @@ public open class SentryOkHttpEventListener( } override fun connectionReleased(call: Call, connection: Connection) { - originalEventListenerMap[call]?.connectionReleased(call, connection) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.connectionReleased(call, connection) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -225,8 +236,9 @@ public open class SentryOkHttpEventListener( } override fun requestHeadersStart(call: Call) { - originalEventListenerMap[call]?.requestHeadersStart(call) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.requestHeadersStart(call) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -234,8 +246,9 @@ public open class SentryOkHttpEventListener( } override fun requestHeadersEnd(call: Call, request: Request) { - originalEventListenerMap[call]?.requestHeadersEnd(call, request) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.requestHeadersEnd(call, request) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -243,8 +256,9 @@ public open class SentryOkHttpEventListener( } override fun requestBodyStart(call: Call) { - originalEventListenerMap[call]?.requestBodyStart(call) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.requestBodyStart(call) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -252,8 +266,9 @@ public open class SentryOkHttpEventListener( } override fun requestBodyEnd(call: Call, byteCount: Long) { - originalEventListenerMap[call]?.requestBodyEnd(call, byteCount) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.requestBodyEnd(call, byteCount) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -266,8 +281,9 @@ public open class SentryOkHttpEventListener( } override fun requestFailed(call: Call, ioe: IOException) { - originalEventListenerMap[call]?.requestFailed(call, ioe) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.requestFailed(call, ioe) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -287,8 +303,9 @@ public open class SentryOkHttpEventListener( } override fun responseHeadersStart(call: Call) { - originalEventListenerMap[call]?.responseHeadersStart(call) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.responseHeadersStart(call) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -296,8 +313,9 @@ public open class SentryOkHttpEventListener( } override fun responseHeadersEnd(call: Call, response: Response) { - originalEventListenerMap[call]?.responseHeadersEnd(call, response) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.responseHeadersEnd(call, response) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -312,8 +330,9 @@ public open class SentryOkHttpEventListener( } override fun responseBodyStart(call: Call) { - originalEventListenerMap[call]?.responseBodyStart(call) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.responseBodyStart(call) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -321,8 +340,9 @@ public open class SentryOkHttpEventListener( } override fun responseBodyEnd(call: Call, byteCount: Long) { - originalEventListenerMap[call]?.responseBodyEnd(call, byteCount) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.responseBodyEnd(call, byteCount) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -335,8 +355,9 @@ public open class SentryOkHttpEventListener( } override fun responseFailed(call: Call, ioe: IOException) { - originalEventListenerMap[call]?.responseFailed(call, ioe) - if (!canCreateEventSpan(call)) { + val originalEventListener = originalEventListenerMap[call] + originalEventListener?.responseFailed(call, ioe) + if (!canCreateEventSpan(originalEventListener)) { return } val okHttpEvent: SentryOkHttpEvent = eventMap[call] ?: return @@ -395,9 +416,6 @@ public open class SentryOkHttpEventListener( originalEventListenerMap[call]?.cacheConditionalHit(call, cachedResponse) } - private fun canCreateEventSpan(call: Call): Boolean = - canCreateEventSpan(originalEventListenerMap[call]) - private fun canCreateEventSpan(originalEventListener: EventListener?): Boolean { // If the wrapped EventListener is ours, we shouldn't create spans, as the originalEventListener // already did it