Skip to content

Commit 34985e7

Browse files
authored
Merge branch 'main' into dependabot/github_actions/actions/create-github-app-token-2.2.1
2 parents 8ea2e19 + b01b11a commit 34985e7

15 files changed

Lines changed: 632 additions & 192 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Fixes
6+
7+
- Session Replay: Improve network body parsing and truncation handling ([#4958](https://github.com/getsentry/sentry-java/pull/4958))
8+
9+
### Internal
10+
11+
- Support `metric` envelope item type ([#4956](https://github.com/getsentry/sentry-java/pull/4956))
12+
313
## 8.28.0
414

515
### Features

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ certifi==2025.7.14
22
charset-normalizer==3.4.2
33
idna==3.10
44
requests==2.32.4
5-
urllib3==2.5.0
5+
urllib3==2.6.0

sentry-android-replay/src/main/java/io/sentry/android/replay/DefaultReplayBreadcrumbConverter.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,12 @@ public open class DefaultReplayBreadcrumbConverter() : ReplayBreadcrumbConverter
241241
networkData.request?.let { request ->
242242
val requestData = mutableMapOf<String, Any?>()
243243
request.size?.let { requestData["size"] = it }
244-
request.body?.let { requestData["body"] = it.value }
244+
request.body?.let {
245+
requestData["body"] = it.body
246+
it.warnings?.let { warnings ->
247+
requestData["warnings"] = warnings.map { warning -> warning.value }
248+
}
249+
}
245250

246251
if (request.headers.isNotEmpty()) {
247252
requestData["headers"] = request.headers
@@ -255,7 +260,12 @@ public open class DefaultReplayBreadcrumbConverter() : ReplayBreadcrumbConverter
255260
networkData.response?.let { response ->
256261
val responseData = mutableMapOf<String, Any?>()
257262
response.size?.let { responseData["size"] = it }
258-
response.body?.let { responseData["body"] = it.value }
263+
response.body?.let {
264+
responseData["body"] = it.body
265+
it.warnings?.let { warnings ->
266+
responseData["warnings"] = warnings.map { warning -> warning.value }
267+
}
268+
}
259269

260270
if (response.headers.isNotEmpty()) {
261271
responseData["headers"] = response.headers

sentry-android-replay/src/test/java/io/sentry/android/replay/DefaultReplayBreadcrumbConverterTest.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -423,15 +423,15 @@ class DefaultReplayBreadcrumbConverterTest {
423423
fakeOkHttpNetworkDetails.setRequestDetails(
424424
ReplayNetworkRequestOrResponse(
425425
100L,
426-
NetworkBody.fromString("request body content"),
426+
NetworkBody("request body content"),
427427
mapOf("Content-Type" to "application/json"),
428428
)
429429
)
430430
fakeOkHttpNetworkDetails.setResponseDetails(
431431
200,
432432
ReplayNetworkRequestOrResponse(
433433
500L,
434-
NetworkBody.fromJsonObject(mapOf("status" to "success", "message" to "OK")),
434+
NetworkBody(mapOf("status" to "success", "message" to "OK")),
435435
mapOf("Content-Type" to "text/plain"),
436436
),
437437
)
@@ -485,15 +485,15 @@ class DefaultReplayBreadcrumbConverterTest {
485485
fakeOkHttpNetworkDetails.setRequestDetails(
486486
ReplayNetworkRequestOrResponse(
487487
150L,
488-
NetworkBody.fromJsonArray(listOf("item1", "item2", "item3")),
488+
NetworkBody(listOf("item1", "item2", "item3")),
489489
mapOf("Content-Type" to "application/json"),
490490
)
491491
)
492492
fakeOkHttpNetworkDetails.setResponseDetails(
493493
404,
494494
ReplayNetworkRequestOrResponse(
495495
550L,
496-
NetworkBody.fromJsonObject(mapOf("status" to "success", "message" to "OK")),
496+
NetworkBody(mapOf("status" to "success", "message" to "OK")),
497497
mapOf("Content-Type" to "text/plain"),
498498
),
499499
)
@@ -540,15 +540,15 @@ class DefaultReplayBreadcrumbConverterTest {
540540
networkRequestData.setRequestDetails(
541541
ReplayNetworkRequestOrResponse(
542542
100L,
543-
NetworkBody.fromString("request body content"),
543+
NetworkBody("request body content"),
544544
mapOf("Content-Type" to "application/json"),
545545
)
546546
)
547547
networkRequestData.setResponseDetails(
548548
200,
549549
ReplayNetworkRequestOrResponse(
550550
100L,
551-
NetworkBody.fromString("respnse body content"),
551+
NetworkBody("response body content"),
552552
mapOf("Content-Type" to "application/json"),
553553
),
554554
)

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,10 @@ public open class SentryOkHttpInterceptor(
317317
val contentTypeString = contentType?.toString()
318318
val maxBodySize = SentryReplayOptions.MAX_NETWORK_BODY_SIZE
319319

320-
val contentLength = responseBody.contentLength()
321-
if (contentLength > maxBodySize * 2) {
322-
return NetworkBody.fromString("[Response body too large: $contentLength bytes]")
323-
}
324-
325320
// Peek at the body (doesn't consume it)
326-
val peekBody = peekBody(maxBodySize.toLong())
321+
// We +1 here in order to properly truncate within NetworkBodyParser.fromBytes
322+
// and be able to distinguish from an oversized request and a request matching maxBodySize
323+
val peekBody = peekBody(maxBodySize.toLong() + 1)
327324
val bodyBytes = peekBody.bytes()
328325

329326
val charset = contentType?.charset(Charsets.UTF_8)?.name() ?: "UTF-8"

sentry/api/sentry.api

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ public final class io/sentry/DataCategory : java/lang/Enum {
362362
public static final field Security Lio/sentry/DataCategory;
363363
public static final field Session Lio/sentry/DataCategory;
364364
public static final field Span Lio/sentry/DataCategory;
365+
public static final field TraceMetric Lio/sentry/DataCategory;
365366
public static final field Transaction Lio/sentry/DataCategory;
366367
public static final field Unknown Lio/sentry/DataCategory;
367368
public static final field UserReport Lio/sentry/DataCategory;
@@ -3138,6 +3139,7 @@ public final class io/sentry/SentryItemType : java/lang/Enum, io/sentry/JsonSeri
31383139
public static final field ReplayVideo Lio/sentry/SentryItemType;
31393140
public static final field Session Lio/sentry/SentryItemType;
31403141
public static final field Span Lio/sentry/SentryItemType;
3142+
public static final field TraceMetric Lio/sentry/SentryItemType;
31413143
public static final field Transaction Lio/sentry/SentryItemType;
31423144
public static final field Unknown Lio/sentry/SentryItemType;
31433145
public static final field UserFeedback Lio/sentry/SentryItemType;
@@ -7479,29 +7481,22 @@ public final class io/sentry/util/UrlUtils$UrlDetails {
74797481
public fun getUrlOrFallback ()Ljava/lang/String;
74807482
}
74817483

7482-
public abstract interface class io/sentry/util/network/NetworkBody {
7483-
public static fun fromJsonArray (Ljava/util/List;)Lio/sentry/util/network/NetworkBody;
7484-
public static fun fromJsonObject (Ljava/util/Map;)Lio/sentry/util/network/NetworkBody;
7485-
public static fun fromString (Ljava/lang/String;)Lio/sentry/util/network/NetworkBody;
7486-
public abstract fun getValue ()Ljava/lang/Object;
7487-
}
7488-
7489-
public final class io/sentry/util/network/NetworkBody$JsonArrayImpl : io/sentry/util/network/NetworkBody {
7490-
public synthetic fun getValue ()Ljava/lang/Object;
7491-
public fun getValue ()Ljava/util/List;
7492-
public fun toString ()Ljava/lang/String;
7493-
}
7494-
7495-
public final class io/sentry/util/network/NetworkBody$JsonObjectImpl : io/sentry/util/network/NetworkBody {
7496-
public synthetic fun getValue ()Ljava/lang/Object;
7497-
public fun getValue ()Ljava/util/Map;
7484+
public final class io/sentry/util/network/NetworkBody {
7485+
public fun <init> (Ljava/lang/Object;)V
7486+
public fun <init> (Ljava/lang/Object;Ljava/util/List;)V
7487+
public fun getBody ()Ljava/lang/Object;
7488+
public fun getWarnings ()Ljava/util/List;
74987489
public fun toString ()Ljava/lang/String;
74997490
}
75007491

7501-
public final class io/sentry/util/network/NetworkBody$StringBodyImpl : io/sentry/util/network/NetworkBody {
7502-
public synthetic fun getValue ()Ljava/lang/Object;
7492+
public final class io/sentry/util/network/NetworkBody$NetworkBodyWarning : java/lang/Enum {
7493+
public static final field BODY_PARSE_ERROR Lio/sentry/util/network/NetworkBody$NetworkBodyWarning;
7494+
public static final field INVALID_JSON Lio/sentry/util/network/NetworkBody$NetworkBodyWarning;
7495+
public static final field JSON_TRUNCATED Lio/sentry/util/network/NetworkBody$NetworkBodyWarning;
7496+
public static final field TEXT_TRUNCATED Lio/sentry/util/network/NetworkBody$NetworkBodyWarning;
75037497
public fun getValue ()Ljava/lang/String;
7504-
public fun toString ()Ljava/lang/String;
7498+
public static fun valueOf (Ljava/lang/String;)Lio/sentry/util/network/NetworkBody$NetworkBodyWarning;
7499+
public static fun values ()[Lio/sentry/util/network/NetworkBody$NetworkBodyWarning;
75057500
}
75067501

75077502
public final class io/sentry/util/network/NetworkBodyParser {

sentry/src/main/java/io/sentry/DataCategory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public enum DataCategory {
1111
Attachment("attachment"),
1212
LogItem("log_item"),
1313
LogByte("log_byte"),
14+
TraceMetric("trace_metric"),
1415
Monitor("monitor"),
1516
Profile("profile"),
1617
ProfileChunkUi("profile_chunk_ui"),

sentry/src/main/java/io/sentry/SentryItemType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public enum SentryItemType implements JsonSerializable {
2323
CheckIn("check_in"),
2424
Feedback("feedback"),
2525
Log("log"),
26+
TraceMetric("trace_metric"),
2627
Span("span"),
2728
Unknown("__unknown__"); // DataCategory.Unknown
2829

sentry/src/main/java/io/sentry/clientreport/ClientReportRecorder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ private DataCategory categoryFromItemType(SentryItemType itemType) {
218218
if (SentryItemType.Span.equals(itemType)) {
219219
return DataCategory.Span;
220220
}
221+
if (SentryItemType.TraceMetric.equals(itemType)) {
222+
return DataCategory.TraceMetric;
223+
}
221224

222225
return DataCategory.Default;
223226
}

sentry/src/main/java/io/sentry/transport/RateLimiter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ private boolean isRetryAfter(final @NotNull String itemType) {
215215
return Collections.singletonList(DataCategory.LogItem);
216216
case "span":
217217
return Collections.singletonList(DataCategory.Span);
218+
case "trace_metric":
219+
return Collections.singletonList(DataCategory.TraceMetric);
218220
default:
219221
return Collections.singletonList(DataCategory.Unknown);
220222
}

0 commit comments

Comments
 (0)