From 969b3c251cfd0e12a472b9fc283000009647053e Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 2 Sep 2025 08:26:59 +0200 Subject: [PATCH 1/4] feat: Add support for vars in SentryStackFrame protocol The vars field previously existed as a property but was never serialized. We use frame.vars to report Godot GDScript trace variables in constructed frames. --- .../io/sentry/protocol/SentryStackFrame.java | 13 ++++++++++--- .../SentryStackFrameSerializationTest.kt | 13 +++++++++++++ .../test/resources/json/sentry_stack_frame.json | 17 ++++++++++++++++- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/sentry/src/main/java/io/sentry/protocol/SentryStackFrame.java b/sentry/src/main/java/io/sentry/protocol/SentryStackFrame.java index 0c2c725df2a..2675813b52c 100644 --- a/sentry/src/main/java/io/sentry/protocol/SentryStackFrame.java +++ b/sentry/src/main/java/io/sentry/protocol/SentryStackFrame.java @@ -29,7 +29,7 @@ public final class SentryStackFrame implements JsonUnknown, JsonSerializable { private @Nullable List postContext; /** Mapping of local variables and expression names that were available in this frame. */ - private @Nullable Map vars; + private @Nullable Map vars; private @Nullable List framesOmitted; @@ -170,11 +170,11 @@ public void setPostContext(final @Nullable List postContext) { this.postContext = postContext; } - public @Nullable Map getVars() { + public @Nullable Map getVars() { return vars; } - public void setVars(final @Nullable Map vars) { + public void setVars(final @Nullable Map vars) { this.vars = vars; } @@ -366,6 +366,7 @@ public static final class JsonKeys { public static final String LOCK = "lock"; public static final String PRE_CONTEXT = "pre_context"; public static final String POST_CONTEXT = "post_context"; + public static final String VARS = "vars"; } @Override @@ -432,6 +433,9 @@ public void serialize(final @NotNull ObjectWriter writer, final @NotNull ILogger if (postContext != null && !postContext.isEmpty()) { writer.name(JsonKeys.POST_CONTEXT).value(logger, postContext); } + if (vars != null && !vars.isEmpty()) { + writer.name(JsonKeys.VARS).value(logger, vars); + } if (unknown != null) { for (String key : unknown.keySet()) { Object value = unknown.get(key); @@ -513,6 +517,9 @@ public static final class Deserializer implements JsonDeserializer) reader.nextObjectOrNull(); break; + case JsonKeys.VARS: + sentryStackFrame.vars = (Map) reader.nextObjectOrNull(); + break; default: if (unknown == null) { unknown = new ConcurrentHashMap<>(); diff --git a/sentry/src/test/java/io/sentry/protocol/SentryStackFrameSerializationTest.kt b/sentry/src/test/java/io/sentry/protocol/SentryStackFrameSerializationTest.kt index ee3e53cabc6..f848ed7080f 100644 --- a/sentry/src/test/java/io/sentry/protocol/SentryStackFrameSerializationTest.kt +++ b/sentry/src/test/java/io/sentry/protocol/SentryStackFrameSerializationTest.kt @@ -54,6 +54,19 @@ class SentryStackFrameSerializationTest { "0a959b53-6bdf-45d1-93ca-936281d7897a", "4e6085a3-1e44-4aa2-b3d9-9b79dca970ed", ) + vars = + mapOf( + "int_var" to 42, + "array_var" to listOf(true, 17, "7a3750d1-9177-4ee2-8016-3ba02fa90291"), + "string_var" to "325ad70e-1a8b-4d2d-ba92-182ee49448b7", + "object_var" to + mapOf( + "int_prop" to 53, + "string_prop" to "93db3ec5-b1ec-4e95-b6d0-b9633c9e03cd", + "bool_prop" to false, + ), + "bool_var" to false, + ) } } diff --git a/sentry/src/test/resources/json/sentry_stack_frame.json b/sentry/src/test/resources/json/sentry_stack_frame.json index 0cd739be875..ee92c22550d 100644 --- a/sentry/src/test/resources/json/sentry_stack_frame.json +++ b/sentry/src/test/resources/json/sentry_stack_frame.json @@ -31,5 +31,20 @@ "2153c99d-2f17-45f1-a173-69e08cc6a219", "0a959b53-6bdf-45d1-93ca-936281d7897a", "4e6085a3-1e44-4aa2-b3d9-9b79dca970ed" - ] + ], + "vars": { + "int_var": 42, + "array_var": [ + true, + 17, + "7a3750d1-9177-4ee2-8016-3ba02fa90291" + ], + "string_var": "325ad70e-1a8b-4d2d-ba92-182ee49448b7", + "object_var": { + "int_prop": 53, + "string_prop": "93db3ec5-b1ec-4e95-b6d0-b9633c9e03cd", + "bool_prop": false + }, + "bool_var": false + } } From 0444d2dbad6342a8d881d00f92cfff9ba4eab747 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 2 Sep 2025 08:28:22 +0200 Subject: [PATCH 2/4] API changes --- sentry/api/sentry.api | 1 + 1 file changed, 1 insertion(+) diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 371d3b43e36..3b85705208e 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -5933,6 +5933,7 @@ public final class io/sentry/protocol/SentryStackFrame$JsonKeys { public static final field RAW_FUNCTION Ljava/lang/String; public static final field SYMBOL Ljava/lang/String; public static final field SYMBOL_ADDR Ljava/lang/String; + public static final field VARS Ljava/lang/String; public fun ()V } From 3a52d55f892dcf869e27c824067e2beb88fb72a4 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Tue, 2 Sep 2025 11:57:53 +0200 Subject: [PATCH 3/4] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce808f2be5e..6d521d77f98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - NOTE: Our `sentry-opentelemetry-agentless-spring` is not working yet for Spring Boot 4. Please use `sentry-opentelemetry-agent` until OpenTelemetry has support for Spring Boot 4. - Replace `UUIDGenerator` implementation with Apache licensed code ([#4662](https://github.com/getsentry/sentry-java/pull/4662)) - Replace `Random` implementation with MIT licensed code ([#4664](https://github.com/getsentry/sentry-java/pull/4664)) +- Add support for `vars` attribute in `SentryStackFrame` ([#4686](https://github.com/getsentry/sentry-java/pull/4686)) ## 8.20.0 From 86865595227920c1e44a5f4e904d06164ee3846e Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Thu, 4 Sep 2025 14:03:40 +0200 Subject: [PATCH 4/4] Apply suggestion to CHANGELOG.md Co-authored-by: Roman Zavarnitsyn --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d521d77f98..50ee1ed6cc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Replace `UUIDGenerator` implementation with Apache licensed code ([#4662](https://github.com/getsentry/sentry-java/pull/4662)) - Replace `Random` implementation with MIT licensed code ([#4664](https://github.com/getsentry/sentry-java/pull/4664)) - Add support for `vars` attribute in `SentryStackFrame` ([#4686](https://github.com/getsentry/sentry-java/pull/4686)) + - **Breaking change**: The type of the `vars` attribute has been changed from `Map` to `Map`. ## 8.20.0