Skip to content

Commit 4e260b3

Browse files
authored
Send breadcrumbs and client error even without transactions (#3087)
* moved breadcrumb sent before span null check in SentryOkHttpEvent.finishEvent() * added client error reporting if call root span is null in SentryOkHttpEvent.finishEvent()
1 parent 1f3652d commit 4e260b3

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
- Support multiple debug-metadata.properties ([#3024](https://github.com/getsentry/sentry-java/pull/3024))
88

9+
### Fixes
10+
11+
- Send breadcrumbs and client error even without transactions ([#3087](https://github.com/getsentry/sentry-java/pull/3087))
12+
913
### Dependencies
1014

1115
- Bump Gradle from v8.4.0 to v8.5.0 ([#3070](https://github.com/getsentry/sentry-java/pull/3070))

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

+16-8
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,22 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req
139139

140140
/** Finishes the call root span, and runs [beforeFinish] on it. Then a breadcrumb is sent. */
141141
fun finishEvent(finishDate: SentryDate? = null, beforeFinish: ((span: ISpan) -> Unit)? = null) {
142-
callRootSpan ?: return
142+
// We put data in the hint and send a breadcrumb
143+
val hint = Hint()
144+
hint.set(TypeCheckHint.OKHTTP_REQUEST, request)
145+
response?.let { hint.set(TypeCheckHint.OKHTTP_RESPONSE, it) }
146+
147+
// We send the breadcrumb even without spans.
148+
hub.addBreadcrumb(breadcrumb, hint)
149+
150+
// No span is created (e.g. no transaction is running)
151+
if (callRootSpan == null) {
152+
// We report the client error even without spans.
153+
clientErrorResponse?.let {
154+
SentryOkHttpUtils.captureClientError(hub, it.request, it)
155+
}
156+
return
157+
}
143158

144159
// We forcefully finish all spans, even if they should already have been finished through finishSpan()
145160
eventSpans.values.filter { !it.isFinished }.forEach {
@@ -159,13 +174,6 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req
159174
} else {
160175
callRootSpan.finish()
161176
}
162-
163-
// We put data in the hint and send a breadcrumb
164-
val hint = Hint()
165-
hint.set(TypeCheckHint.OKHTTP_REQUEST, request)
166-
response?.let { hint.set(TypeCheckHint.OKHTTP_RESPONSE, it) }
167-
168-
hub.addBreadcrumb(breadcrumb, hint)
169177
return
170178
}
171179

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

+24-2
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@ class SentryOkHttpEventTest {
123123
}
124124

125125
@Test
126-
fun `when root span is null, no breadcrumb is created`() {
126+
fun `when root span is null, breadcrumb is created anyway`() {
127127
val sut = fixture.getSut(currentSpan = null)
128128
assertNull(sut.callRootSpan)
129129
sut.finishEvent()
130-
verify(fixture.hub, never()).addBreadcrumb(any<Breadcrumb>(), anyOrNull())
130+
verify(fixture.hub).addBreadcrumb(any<Breadcrumb>(), anyOrNull())
131131
}
132132

133133
@Test
@@ -572,6 +572,28 @@ class SentryOkHttpEventTest {
572572
sut.setClientErrorResponse(clientErrorResponse)
573573
verify(fixture.hub, never()).captureEvent(any(), any<Hint>())
574574
sut.finishEvent()
575+
assertNotNull(sut.callRootSpan)
576+
verify(fixture.hub).captureEvent(
577+
argThat {
578+
throwable is SentryHttpClientException &&
579+
throwable!!.message!!.startsWith("HTTP Client Error with status code: ")
580+
},
581+
argThat<Hint> {
582+
get(TypeCheckHint.OKHTTP_REQUEST) != null &&
583+
get(TypeCheckHint.OKHTTP_RESPONSE) != null
584+
}
585+
)
586+
}
587+
588+
@Test
589+
fun `setClientErrorResponse will capture the client error on finishEvent even when no span is running`() {
590+
val sut = fixture.getSut(currentSpan = null)
591+
val clientErrorResponse = mock<Response>()
592+
whenever(clientErrorResponse.request).thenReturn(fixture.mockRequest)
593+
sut.setClientErrorResponse(clientErrorResponse)
594+
verify(fixture.hub, never()).captureEvent(any(), any<Hint>())
595+
sut.finishEvent()
596+
assertNull(sut.callRootSpan)
575597
verify(fixture.hub).captureEvent(
576598
argThat {
577599
throwable is SentryHttpClientException &&

0 commit comments

Comments
 (0)