Skip to content
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
d7f8249
Explicit singleton
limbonaut Aug 19, 2025
cdaa093
Refactor Sentry class registration
limbonaut Aug 19, 2025
0a91456
Auto-initialize in a separate step, ensure internal SDK is ready early
limbonaut Aug 19, 2025
044263a
Rename func => _auto_initialize()
limbonaut Aug 19, 2025
d809e8b
Move event processor initialization to prepare step
limbonaut Aug 19, 2025
62bb04f
Correct comment
limbonaut Aug 19, 2025
6e4835f
Fix Android compilation
limbonaut Aug 19, 2025
6cba510
Simplify Android enabling code
limbonaut Aug 19, 2025
a721f65
Rename initialize => init
limbonaut Aug 19, 2025
6cf9fd7
Update CHANGELOG.md
limbonaut Aug 20, 2025
c61ad72
Return plugin check on Android
limbonaut Aug 20, 2025
744d5a3
Update CHANGELOG.md
limbonaut Aug 20, 2025
5670b80
Merge branch 'main' into ref/impove-initialization-extracted
limbonaut Aug 20, 2025
847f49e
Add SentrySDK.init(), close(), is_enabled()
limbonaut Aug 19, 2025
1250511
Remove enabled flag and move logger registration into init()
limbonaut Aug 20, 2025
ee888c4
Add error handling for _configure
limbonaut Aug 20, 2025
8a8304f
Move contexts init logic into init()
limbonaut Aug 20, 2025
9310679
Whitespace fix
limbonaut Aug 20, 2025
0b5f933
Expose new methods, and add docs
limbonaut Aug 20, 2025
b25c545
Add tests for lifecycle methods
limbonaut Aug 21, 2025
dc71c41
Rename lifecycle test to test_sdk_lifecycle.gd
limbonaut Aug 21, 2025
3356bc2
Add tests for closing SDK
limbonaut Aug 21, 2025
9b31037
Fix issues with SentryLogger connecting to signal
limbonaut Aug 21, 2025
a21f3e9
Fix initialized flag should be set to false in NativeSDK on close(), and
limbonaut Aug 21, 2025
b8a9732
Merge branch 'main' into ref/improve-initialization
limbonaut Sep 9, 2025
11fcc68
Rename enabled/disabled options, remove them from exposed properties,
limbonaut Sep 10, 2025
bb1681d
Remove configuration script option
limbonaut Sep 10, 2025
b6c0a9c
Add configuration callback in init()
limbonaut Sep 10, 2025
6f07401
Remove SentryConfiguration class
limbonaut Sep 10, 2025
5c2a211
Merge branch 'main' into ref/improve-initialization
limbonaut Sep 10, 2025
1dbdbcb
Replace configuration script with init() & before_send example from
limbonaut Sep 10, 2025
320a903
Adjust isolation tests for new init
limbonaut Sep 10, 2025
bdb697e
Remove testing_configuration.gd
limbonaut Sep 10, 2025
38f016b
Adjust normal test suites for the new init
limbonaut Sep 10, 2025
f5a7da9
Update docs
limbonaut Sep 10, 2025
a26c9a5
Update SentrySDK.xml
limbonaut Sep 10, 2025
9baac57
Update docs with initialization & configuration examples
limbonaut Sep 10, 2025
1ee4106
Fix user not initialized if init() is not called
limbonaut Sep 10, 2025
cc00783
Restore SDK lifecycle isolated test
limbonaut Sep 10, 2025
a2c541b
Cosmetic fixes for docs
limbonaut Sep 10, 2025
3ee3da5
Auto doc fixes
limbonaut Sep 10, 2025
680d16f
Remove test_sdk_close as redundant
limbonaut Sep 10, 2025
d548380
Move contexts initialization into sentry::contexts
limbonaut Sep 10, 2025
e4b1ac3
Refactor context initialization to avoid Godot errors
limbonaut Sep 10, 2025
c99f787
Rename initialize => init on Android
limbonaut Sep 10, 2025
dd112bd
Revert "Move contexts initialization into sentry::contexts"
limbonaut Sep 10, 2025
2e15faf
Only close SDK if enabled in destructors
limbonaut Sep 10, 2025
888c017
Remove unused should_delay_contexts function
limbonaut Sep 10, 2025
c591cd9
Update CHANGELOG.md
limbonaut Sep 10, 2025
cd31f66
Update CHANGELOG.md
limbonaut Sep 10, 2025
89dbb9b
Fix link in CHANGELOG
limbonaut Sep 10, 2025
03dd1bb
Don't auto-initialize if DSN is empty
limbonaut Sep 11, 2025
973403f
Explain gui-only options in SentryOptions
limbonaut Sep 12, 2025
940df89
Fix unterminated bbcode
limbonaut Sep 12, 2025
521276e
Sync with docs
limbonaut Sep 12, 2025
7c34f6e
Update SentryOptions.xml
limbonaut Sep 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class SentryAndroidGodotPlugin(godot: Godot) : GodotPlugin(godot) {
}

@UsedByGodot
fun initialize(
fun init(
beforeSendHandlerId: Long,
dsn: String,
debug: Boolean,
Expand Down Expand Up @@ -154,6 +154,16 @@ class SentryAndroidGodotPlugin(godot: Godot) : GodotPlugin(godot) {
}
}

@UsedByGodot
fun close() {
Sentry.close()
}

@UsedByGodot
fun isEnabled(): Boolean {
return Sentry.isEnabled()
}

@UsedByGodot
fun addFileAttachment(path: String, filename: String, contentType: String, attachmentType: String) {
val attachment = Attachment(
Expand Down
41 changes: 0 additions & 41 deletions doc_classes/SentryConfiguration.xml

This file was deleted.

12 changes: 3 additions & 9 deletions doc_classes/SentryOptions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Contains Sentry SDK options.
</brief_description>
<description>
Defines options for the Sentry SDK. These options can be modified in the Project Settings under the [b]Sentry[/b] category or through a user configuration script. See [SentryConfiguration] for details on creating such a script.
Defines options for the Sentry SDK. These options can be modified in the Project Settings under the [b]Sentry[/b] category or from code through a configuration callback using manual initialization. See [method SentrySDK.init].
To learn more, visit [url=https://docs.sentry.io/platforms/godot/configuration/options/]Options documentation[/url].
</description>
<tutorials>
Expand All @@ -29,7 +29,7 @@
[/codeblock]
</member>
<member name="before_send" type="Callable" setter="set_before_send" getter="get_before_send" default="Callable()">
If assigned, this callback runs before an event is sent to Sentry. It takes [SentryEvent] as a parameter and return either the same event object, with or without modifications, or [code]null[/code] to skip reporting the event. You can assign it in a [SentryConfiguration] script. To check if the event is a crash, use [method SentryEvent.is_crash].
If assigned, this callback runs before an event is sent to Sentry. It takes [SentryEvent] as a parameter and return either the same event object, with or without modifications, or [code]null[/code] to skip reporting the event. You can assign it in a configuration callback using manual initialization (see [method SentrySDK.init]). To check if the event is a crash, use [method SentryEvent.is_crash].
[codeblock]
func _before_send(event: SentryEvent) -&gt; SentryEvent:
if event.environment == "editor_dev_run":
Expand All @@ -49,20 +49,14 @@
<member name="diagnostic_level" type="int" setter="set_diagnostic_level" getter="get_diagnostic_level" enum="SentrySDK.Level" default="0">
Specifies the minimum level of messages to be printed if [member debug] is enabled.
</member>
<member name="disabled_in_editor_play" type="bool" setter="set_disabled_in_editor_play" getter="is_disabled_in_editor_play" default="false">
If [code]true[/code], the SDK will not initialize when you play/run your project from within the Godot editor (using the play button or F5).
</member>
<member name="dist" type="String" setter="set_dist" getter="get_dist" default="&quot;&quot;">
The application's distribution. Distributions are used to disambiguate build or deployment variants of the same release of an application.
</member>
<member name="dsn" type="String" setter="set_dsn" getter="get_dsn" default="&quot;&quot;">
Data Source Name (DSN): Specifies where the SDK should send the events. If this value is not provided, the SDK will try to read it from the [code]SENTRY_DSN[/code] environment variable. If that variable also does not exist, the SDK will just not send any events.
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
If [code]false[/code], the SDK will not initialize. This is useful for temporarily disabling the SDK in the Project Settings, or in a [SentryConfiguration] script.
</member>
<member name="environment" type="String" setter="set_environment" getter="get_environment" default="&quot;editor_dev&quot;">
Environments indicate where an error occurred, such as in a release export, headless server, QA build, or another deployment. The SDK automatically detects Godot-specific environments, such as [code]headless_server[/code] and [code]export_release[/code], but you can also assign it in a [SentryConfiguration] script.
Environments indicate where an error occurred, such as in a release export, headless server, QA build, or another deployment. The SDK automatically detects Godot-specific environments, such as [code]headless_server[/code] and [code]export_release[/code], but you can also assign it in a configuration callback using manual initialization (see [method SentrySDK.init]).
To learn more, visit [url=https://docs.sentry.io/platforms/godot/configuration/environments/]Environments documentation[/url].
</member>
<member name="logger_breadcrumb_mask" type="int" setter="set_logger_breadcrumb_mask" getter="get_logger_breadcrumb_mask" enum="SentryOptions.GodotErrorMask" is_bitfield="true" default="15">
Expand Down
35 changes: 35 additions & 0 deletions doc_classes/SentrySDK.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
Captures an event with [param message] and sends it to Sentry, returning the event ID.
</description>
</method>
<method name="close">
<return type="void" />
<description>
Closes the SDK and flushes any pending events to ensure all queued data is sent to Sentry before shutdown. Called automatically when the application exits.
</description>
</method>
<method name="create_event" qualifiers="const">
<return type="SentryEvent" />
<description>
Expand All @@ -62,6 +68,35 @@
Returns the currently set user. See [SentryUser].
</description>
</method>
<method name="init">
<return type="void" />
<param index="0" name="configuration_callback" type="Callable" default="Callable()" />
<description>
Initializes the SDK. Called automatically during startup if "Auto Init" is enabled in the project settings.
Manual initialization is only needed when you want to control the exact timing of SDK startup, or when you need to initialize options from code, or use callbacks such as [member SentryOptions.before_send]. Make sure to disable "Auto Init" in the project settings if you intend to manually initialize the SDK.
[b]Note[/b]: The earliest place to initialize Sentry from script is in the [method MainLoop._initialize].
You can customize the SDK's options by passing a [param configuration_callback] function. Here's a complete example:
[codeblock]
class_name ProjectMainLoop
extends SceneTree
# Tip: Assign ProjectMainLoop as your main loop type in the project settings
# under `application/run/main_loop_type`.

func _initialize() -&gt; void:
SentrySDK.init(func(options: SentryOptions) -&gt; void:
options.debug = true
options.release = "[email protected]"
options.environment = "production"
options.before_send = _on_before_send_to_sentry
)

func _on_before_send_to_sentry(event: SentryEvent) -&gt; SentryEvent:
# Process event and return either the same event object,
# with or withour modifications, or null to skip reporting the event.
return event
[/codeblock]
</description>
</method>
<method name="is_enabled" qualifiers="const">
<return type="bool" />
<description>
Expand Down
31 changes: 0 additions & 31 deletions project/example_configuration.gd

This file was deleted.

1 change: 0 additions & 1 deletion project/example_configuration.gd.uid

This file was deleted.

3 changes: 2 additions & 1 deletion project/project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ config_version=5
config/name="Sentry demo project"
config/version="1.0.0-beta.1"
run/main_scene="uid://cqiowj0jydds1"
run/main_loop_type="ProjectMainLoop"
config/features=PackedStringArray("4.5")
run/flush_stdout_on_print=true
config/icon="uid://djdyhgbcdue6n"
Expand Down Expand Up @@ -45,8 +46,8 @@ textures/vram_compression/import_etc2_astc=true

[sentry]

options/auto_init=false
options/dsn="https://[email protected]/6680910"
options/configuration_script="uid://dmavxxyqbqght"
options/attach_screenshot=true
options/attach_scene_tree=true
logger/include_variables=true
36 changes: 36 additions & 0 deletions project/project_main_loop.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
class_name ProjectMainLoop
extends SceneTree
## Example of initializing and configuring Sentry from code.
##
## The earliest place to initialize Sentry in script is in the MainLoop._initialize().
## Tip: You can assign "ProjectMainLoop" as your main loop class in the project settings
## under `application/run/main_loop_type`.


func _initialize() -> void:
SentrySDK.init(func(options: SentryOptions) -> void:
print("INFO: [ProjectMainLoop] Initializing SDK from GDScript")

options.debug = true
options.release = "sentry-godot-demo@" + ProjectSettings.get_setting("application/config/version")
options.environment = "demo"

# Set up event callbacks
options.before_send = _on_before_send_to_sentry
)

# Post-initialize
# SentrySDK.add_attachment(...)
# ...


## before_send example
func _on_before_send_to_sentry(ev: SentryEvent) -> SentryEvent:
print("INFO: [ProjectMainLoop] Processing event: ", ev.id)
if ev.message.contains("Bruno"):
print("INFO: [ProjectMainLoop] Removing sensitive information from the event")
ev.message = ev.message.replace("Bruno", "REDACTED")
elif ev.message == "junk":
print("INFO: [ProjectMainLoop] Discarding event with message 'junk'")
return null
return ev
1 change: 1 addition & 0 deletions project/project_main_loop.gd.uid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://ckyjdnckvfm8b
25 changes: 13 additions & 12 deletions project/test/isolated/test_limit_events_per_frame.gd
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ signal callback_processed
var _num_events: int = 0


static func configure_options(options: SentryOptions) -> void:
# Only one error is allowed to be logged as event per processed frame.
options.logger_limits.events_per_frame = 1
# Make sure other limits are not interfering.
options.logger_limits.repeated_error_window_ms = 0
options.logger_limits.throttle_events = 88


func before_test() -> void:
SentrySDK._set_before_send(_before_send)
func before() -> void:
SentrySDK.init(func(options: SentryOptions) -> void:
# Only one error is allowed to be logged as event per processed frame.
options.logger_limits.events_per_frame = 1
# Make sure other limits are not interfering.
options.logger_limits.repeated_error_window_ms = 0
options.logger_limits.throttle_events = 88
options.before_send = _before_send
)


func _before_send(_ev: SentryEvent) -> SentryEvent:
Expand All @@ -27,10 +26,12 @@ func _before_send(_ev: SentryEvent) -> SentryEvent:

## Only one error should be logged within 1 processed frame.
func test_events_per_frame_limit() -> void:
var monitor := monitor_signals(self, false)
monitor_signals(self, false)

push_error("dummy-error")
push_error("dummy-error")
push_error("dummy-error")
await assert_signal(monitor).is_emitted("callback_processed")

await assert_signal(self).is_emitted("callback_processed")
await get_tree().create_timer(0.1).timeout
assert_int(_num_events).is_equal(1)
19 changes: 9 additions & 10 deletions project/test/isolated/test_limit_repeating_error_window.gd
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ signal callback_processed
var _num_events: int = 0


static func configure_options(options: SentryOptions) -> void:
# Ignore duplicate errors within 1 second window.
options.logger_limits.repeated_error_window_ms = 1000
# Make sure other limits are not interfering.
options.logger_limits.events_per_frame = 88
options.logger_limits.throttle_events = 88


func before_test() -> void:
SentrySDK._set_before_send(_before_send)
func before() -> void:
SentrySDK.init(func(options: SentryOptions) -> void:
# Ignore duplicate errors within 1 second window.
options.logger_limits.repeated_error_window_ms = 1000
# Make sure other limits are not interfering.
options.logger_limits.events_per_frame = 88
options.logger_limits.throttle_events = 88
options.before_send = _before_send
)


func _before_send(_ev: SentryEvent) -> SentryEvent:
Expand Down
21 changes: 10 additions & 11 deletions project/test/isolated/test_limit_throttling.gd
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@ signal callback_processed
var _num_events: int = 0


static func configure_options(options: SentryOptions) -> void:
# Allow only two errors to be logged as events within 1 second time window.
options.logger_limits.throttle_events = 2
options.logger_limits.throttle_window_ms = 1000
# Make sure other limits are not interfering.
options.logger_limits.events_per_frame = 88
options.logger_limits.repeated_error_window_ms = 0


func before_test() -> void:
SentrySDK._set_before_send(_before_send)
func before() -> void:
SentrySDK.init(func(options: SentryOptions) -> void:
# Allow only two errors to be logged as events within 1 second time window.
options.logger_limits.throttle_events = 2
options.logger_limits.throttle_window_ms = 1000
# Make sure other limits are not interfering.
options.logger_limits.events_per_frame = 88
options.logger_limits.repeated_error_window_ms = 0
options.before_send = _before_send
)


func _before_send(_ev: SentryEvent) -> SentryEvent:
Expand Down
36 changes: 18 additions & 18 deletions project/test/isolated/test_logger_disabled.gd
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@ signal callback_processed
var _num_events: int = 0


static func configure_options(options: SentryOptions) -> void:
options.logger_enabled = false
func before() -> void:
SentrySDK.init(func(options: SentryOptions) -> void:
options.logger_enabled = false

# Make sure other limits are not interfering.
options.logger_limits.events_per_frame = 88
options.logger_limits.throttle_events = 88
options.logger_limits.repeated_error_window_ms = 0
options.logger_limits.throttle_window_ms = 0
# Make sure other limits are not interfering.
options.logger_limits.events_per_frame = 88
options.logger_limits.throttle_events = 88
options.logger_limits.repeated_error_window_ms = 0
options.logger_limits.throttle_window_ms = 0


func before_test() -> void:
SentrySDK._set_before_send(_before_send)
options.before_send = _before_send
)


func _before_send(_ev: SentryEvent) -> SentryEvent:
_num_events += 1
callback_processed.emit()
return null
_num_events += 1
callback_processed.emit()
return null


func test_event_and_breadcrumb_masks() -> void:
var monitor := monitor_signals(self, false)
push_error("dummy-error")
push_warning("dummy-warning")
await assert_signal(monitor).is_not_emitted("callback_processed")
var monitor := monitor_signals(self, false)
push_error("dummy-error")
push_warning("dummy-warning")
await assert_signal(monitor).is_not_emitted("callback_processed")

assert_int(_num_events).is_equal(0)
assert_int(_num_events).is_equal(0)
Loading
Loading