diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9b67cf5a..b4409a62 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
### Features
- Add support for script context and variables on Apple platforms ([#306](https://github.com/getsentry/sentry-godot/pull/306))
+- Add SentryEvent.to_json() ([#329](https://github.com/getsentry/sentry-godot/pull/329))
### Improvements
diff --git a/android_lib/src/main/java/io/sentry/godotplugin/SentryAndroidGodotPlugin.kt b/android_lib/src/main/java/io/sentry/godotplugin/SentryAndroidGodotPlugin.kt
index ea46b9f5..5c08fc1e 100644
--- a/android_lib/src/main/java/io/sentry/godotplugin/SentryAndroidGodotPlugin.kt
+++ b/android_lib/src/main/java/io/sentry/godotplugin/SentryAndroidGodotPlugin.kt
@@ -4,6 +4,7 @@ import android.util.Log
import io.sentry.Attachment
import io.sentry.Breadcrumb
import io.sentry.Hint
+import io.sentry.ISerializer
import io.sentry.Sentry
import io.sentry.SentryEvent
import io.sentry.SentryLevel
@@ -20,6 +21,7 @@ import org.godotengine.godot.plugin.GodotPlugin
import org.godotengine.godot.plugin.UsedByGodot
import org.godotengine.godot.variant.Callable
import java.io.File
+import java.io.StringWriter
import kotlin.random.Random
@@ -381,6 +383,15 @@ class SentryAndroidGodotPlugin(godot: Godot) : GodotPlugin(godot) {
return getEvent(eventHandle)?.isCrashed == true
}
+ @UsedByGodot
+ fun eventToJson(eventHandle: Int): String {
+ val event = getEvent(eventHandle) ?: return ""
+ val serializer: ISerializer = Sentry.getCurrentScopes().options.serializer
+ val writer = StringWriter()
+ serializer.serialize(event, writer)
+ return writer.toString()
+ }
+
@UsedByGodot
fun createException(type: String, value: String): Int {
val exception = SentryException()
diff --git a/doc_classes/SentryEvent.xml b/doc_classes/SentryEvent.xml
index e07c5ac4..0f8a7e78 100644
--- a/doc_classes/SentryEvent.xml
+++ b/doc_classes/SentryEvent.xml
@@ -38,6 +38,12 @@
Sets a tag with the specified [param key] to the given [param value].
+
+
+
+ Serializes the event to JSON string.
+
+
diff --git a/src/sentry/android/android_event.cpp b/src/sentry/android/android_event.cpp
index 025210a3..43038357 100644
--- a/src/sentry/android/android_event.cpp
+++ b/src/sentry/android/android_event.cpp
@@ -136,6 +136,11 @@ bool AndroidEvent::is_crash() const {
return android_plugin->call(ANDROID_SN(eventIsCrash), event_handle);
}
+String AndroidEvent::to_json() const {
+ ERR_FAIL_NULL_V(android_plugin, String());
+ return android_plugin->call(ANDROID_SN(eventToJson), event_handle);
+}
+
AndroidEvent::AndroidEvent(Object *p_android_plugin, int32_t p_event_handle) {
android_plugin = p_android_plugin;
event_handle = p_event_handle;
diff --git a/src/sentry/android/android_event.h b/src/sentry/android/android_event.h
index 4f6b63cf..145f0c4d 100644
--- a/src/sentry/android/android_event.h
+++ b/src/sentry/android/android_event.h
@@ -57,6 +57,8 @@ class AndroidEvent : public SentryEvent {
virtual bool is_crash() const override;
+ virtual String to_json() const override;
+
void set_as_borrowed() { is_borrowed = true; }
AndroidEvent() {}
diff --git a/src/sentry/android/android_string_names.cpp b/src/sentry/android/android_string_names.cpp
index c4f8b4f0..e5f20d9b 100644
--- a/src/sentry/android/android_string_names.cpp
+++ b/src/sentry/android/android_string_names.cpp
@@ -53,6 +53,7 @@ AndroidStringNames::AndroidStringNames() {
eventGetTag = StringName("eventGetTag");
eventMergeContext = StringName("eventMergeContext");
eventIsCrash = StringName("eventIsCrash");
+ eventToJson = StringName("eventToJson");
// Exceptions.
createException = StringName("createException");
diff --git a/src/sentry/android/android_string_names.h b/src/sentry/android/android_string_names.h
index 3467cba7..81922a27 100644
--- a/src/sentry/android/android_string_names.h
+++ b/src/sentry/android/android_string_names.h
@@ -65,6 +65,7 @@ class AndroidStringNames {
StringName eventGetTag;
StringName eventMergeContext;
StringName eventIsCrash;
+ StringName eventToJson;
// Exceptions.
StringName createException;
diff --git a/src/sentry/cocoa/cocoa_event.h b/src/sentry/cocoa/cocoa_event.h
index 95e060f4..4d037c5f 100644
--- a/src/sentry/cocoa/cocoa_event.h
+++ b/src/sentry/cocoa/cocoa_event.h
@@ -53,6 +53,8 @@ class CocoaEvent : public sentry::SentryEvent {
virtual bool is_crash() const override;
+ virtual String to_json() const override;
+
CocoaEvent(objc::SentryEvent *p_cocoa_event);
CocoaEvent();
virtual ~CocoaEvent() override;
diff --git a/src/sentry/cocoa/cocoa_event.mm b/src/sentry/cocoa/cocoa_event.mm
index c5d1ff8c..d3063e8b 100644
--- a/src/sentry/cocoa/cocoa_event.mm
+++ b/src/sentry/cocoa/cocoa_event.mm
@@ -270,6 +270,20 @@
return cocoa_event.error != nil;
}
+String CocoaEvent::to_json() const {
+ ERR_FAIL_NULL_V(cocoa_event, String());
+
+ NSDictionary *event_dict = [cocoa_event serialize];
+
+ NSError *error = nil;
+ NSData *json_data = [NSJSONSerialization dataWithJSONObject:event_dict
+ options:0
+ error:&error];
+ ERR_FAIL_COND_V(error != nil, "Sentry: Failed to serialize event to JSON: " + string_from_objc(error.localizedDescription));
+
+ return String::utf8((const char *)json_data.bytes, json_data.length);
+}
+
CocoaEvent::CocoaEvent() :
cocoa_event([[objc::SentryEvent alloc] init]) {
}
diff --git a/src/sentry/disabled/disabled_event.h b/src/sentry/disabled/disabled_event.h
index 437e8ff3..90ad6200 100644
--- a/src/sentry/disabled/disabled_event.h
+++ b/src/sentry/disabled/disabled_event.h
@@ -56,6 +56,8 @@ class DisabledEvent : public SentryEvent {
virtual void add_exception(const Exception &p_exception) override {}
virtual bool is_crash() const override { return false; }
+
+ virtual String to_json() const override { return ""; }
};
} // namespace sentry
diff --git a/src/sentry/native/native_event.cpp b/src/sentry/native/native_event.cpp
index 20aa51b4..486c0512 100644
--- a/src/sentry/native/native_event.cpp
+++ b/src/sentry/native/native_event.cpp
@@ -215,6 +215,13 @@ bool NativeEvent::is_crash() const {
return _is_crash;
}
+String NativeEvent::to_json() const {
+ char *json_value = sentry_value_to_json(native_event);
+ String json_str = String::utf8(json_value);
+ sentry_free(json_value);
+ return json_str;
+}
+
NativeEvent::NativeEvent(sentry_value_t p_native_event, bool p_is_crash) :
_is_crash(p_is_crash) {
if (sentry_value_refcount(p_native_event) > 0) {
diff --git a/src/sentry/native/native_event.h b/src/sentry/native/native_event.h
index 9f813512..136d79c4 100644
--- a/src/sentry/native/native_event.h
+++ b/src/sentry/native/native_event.h
@@ -56,6 +56,8 @@ class NativeEvent : public SentryEvent {
virtual bool is_crash() const override;
+ virtual String to_json() const override;
+
NativeEvent(sentry_value_t p_event, bool p_is_crash);
NativeEvent();
virtual ~NativeEvent() override;
diff --git a/src/sentry/sentry_event.cpp b/src/sentry/sentry_event.cpp
index 6f374aa0..b797f329 100644
--- a/src/sentry/sentry_event.cpp
+++ b/src/sentry/sentry_event.cpp
@@ -27,6 +27,7 @@ void SentryEvent::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_tag", "key"), &SentryEvent::remove_tag);
ClassDB::bind_method(D_METHOD("get_tag", "key"), &SentryEvent::get_tag);
ClassDB::bind_method(D_METHOD("is_crash"), &SentryEvent::is_crash);
+ ClassDB::bind_method(D_METHOD("to_json"), &SentryEvent::to_json);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "id"), "", "get_id");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "message"), "set_message", "get_message");
diff --git a/src/sentry/sentry_event.h b/src/sentry/sentry_event.h
index f58ab15e..98c4f8ff 100644
--- a/src/sentry/sentry_event.h
+++ b/src/sentry/sentry_event.h
@@ -76,6 +76,8 @@ class SentryEvent : public RefCounted {
virtual bool is_crash() const = 0;
+ virtual String to_json() const = 0;
+
virtual ~SentryEvent() = default;
};