Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
65 changes: 61 additions & 4 deletions docs/platforms/godot/configuration/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -197,28 +197,41 @@ This option is turned on by default.
Specifies the types of errors captured as breadcrumbs. Accepts a single value or a bitwise combination of `GodotErrorMask` masks. The default value captures native errors, warnings, script and shader errors (`MASK_ERROR | MASK_WARNING | MASK_SCRIPT | MASK_SHADER`).

`GodotErrorMask` values:

- `MASK_NONE`: No logger errors will be captured.
- `MASK_ERROR`: Native errors will be captured. These are typically C++ errors, which may also originate from a script.
- `MASK_WARNING`: Warnings will be captured.
- `MASK_SCRIPT`: Script errors will be captured.
- `MASK_SHADER`: Shader errors will be captured.

```GDScript
```gdscript {tabTitle:GDScript} {mdExpandTabs}
var mask = SentryOptions.MASK_ERROR | SentryOptions.MASK_SCRIPT
options.logger_breadcrumb_mask = mask
```

```csharp {tabTitle:C#}
var mask = SentryGodotOptions.GodotLoggerEventMask.Error
| SentryGodotOptions.GodotLoggerEventMask.Script;
options.LoggerBreadcrumbMask = mask;
```

</SdkOption>

<SdkOption name="logger_event_mask" type="int" defaultValue="13 (All except warnings)">

Specifies the types of errors captured as events. Accepts a single value or a bitwise combination of `GodotErrorMask` masks. The default value captures native, script and shader errors (`MASK_ERROR | MASK_SCRIPT` | `MASK_SHADER`).

```GDScript
```gdscript {tabTitle:GDScript} {mdExpandTabs}
var mask = SentryOptions.MASK_ERROR | SentryOptions.MASK_SCRIPT
options.logger_event_mask = mask
```

```csharp {tabTitle:C#}
var mask = SentryGodotOptions.GodotLoggerEventMask.Error
| SentryGodotOptions.GodotLoggerEventMask.Script;
options.LoggerEventMask = mask;
```

</SdkOption>

<SdkOption name="logger_include_source" type="bool" defaultValue="true">
Expand Down Expand Up @@ -278,7 +291,7 @@ thread-safe APIs and only use Godot-specific APIs after you've checked that you'

If assigned, this callback runs before an event is sent to Sentry. You can only set it [programmatically](#programmatic-configuration). It takes `SentryEvent` as a parameter and returns either the same event object, with or without modifications, or `null` to skip reporting the event. This can be used, for instance, for stripping PII before sending.

```GDScript
```gdscript {tabTitle:GDScript} {mdExpandTabs}
func _before_send(event: SentryEvent) -> SentryEvent:
if event.environment.contains("editor"):
# Discard event if running from the editor.
Expand All @@ -291,6 +304,29 @@ func _before_send(event: SentryEvent) -> SentryEvent:
return event
```

```csharp {tabTitle:C#}
// The .NET hook filters events captured from your C# code.
options.SetBeforeSend((sentryEvent, hint) =>
{
if (sentryEvent.Environment?.Contains("editor") == true)
{
// Discard the event if running from the editor.
return null;
}

foreach (var exception in sentryEvent.SentryExceptions ?? [])
{
if (exception.Value?.Contains("Bruno") == true)
{
// Remove sensitive information from the event.
exception.Value = exception.Value.Replace("Bruno", "REDACTED");
}
}

return sentryEvent;
});
```

</SdkOption>

<SdkOption name="before_capture_screenshot" type="Callable">
Expand All @@ -304,14 +340,20 @@ func _before_capture_screenshot(event: SentryEvent) -> bool:
return true
```

<Alert title="Note">

This callback isn't available in the .NET layer yet, so it can only be set from GDScript.

</Alert>

</SdkOption>

<SdkOption name="before_send_log" type="Callable" availableSince="1.2.0">

If assigned, this callback will be called before sending a log message to Sentry.
It can be used to modify the log message or prevent it from being sent.

```GDScript
```gdscript {tabTitle:GDScript} {mdExpandTabs}
func _before_send_log(log_entry: SentryLog) -> SentryLog:
# Filter junk.
if log_entry.body == "Junk message":
Expand All @@ -323,4 +365,19 @@ func _before_send_log(log_entry: SentryLog) -> SentryLog:
return log_entry
```

```csharp {tabTitle:C#}
// The .NET hook applies to logs emitted from your C# code.
options.SetBeforeSendLog(log =>
{
// Filter junk.
if (log.Message == "Junk message")
{
return null;
}
// Add custom attributes.
log.SetAttribute("current_scene", currentScene.Name);
return log;
});
```

</SdkOption>
29 changes: 29 additions & 0 deletions docs/platforms/godot/configuration/stack-traces.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ For more information, refer to [Building from Source](https://docs.godotengine.o
## Getting Godot Source

Start in a terminal with Git available. Clone Godot Engine repository and switch to your [preferred version tag](https://github.com/godotengine/godot/releases) (or branch):

```bash
git clone https://github.com/godotengine/godot
cd godot
Expand Down Expand Up @@ -135,18 +136,22 @@ With your custom templates compiled, you can now export your project with debug
3. Configure the custom template in the **Options** tab:

**For Windows/Linux:**

- Find the **Custom Template** section
- Under **Release**, browse and select your compiled template executable from the `bin/` directory

**For macOS**

- Find the **Custom Template** section
- Under **Release**, browse and select `godot_macos.zip` bundle from the `bin/` directory

**For iOS:**

- Find the **Custom Template** section
- Under both **Release** and **Debug**, browse and select the same `godot_ios.zip` bundle from the `bin/` directory

**For Android:**

- Enable **Gradle Build** in the **Gradle** section
- Set **Android Source Template** to point to the `android_source.zip` file generated during compilation
- Install the Android build template by navigating to **Project > Install Android Build Template...** in the editor menu
Expand Down Expand Up @@ -280,6 +285,30 @@ Congratulations! You're all set up. Your exported project should now produce sym

![Symbolicated Issue](./imgs/symbolicated_issue.png)

## C# (Managed Code)

The steps above cover native engine and GDExtension (C/C++) frames. Stack frames from your <PlatformLink to="/dotnet/">C# code</PlatformLink> are symbolicated separately. What you need to do depends on the platform:

- **Desktop (Windows, Linux, and macOS):** No upload is required if you ship debug symbols with your game. The SDK then resolves file names and line numbers at runtime from the `.pdb` files next to your game, which the **dotnet/include_debug_symbols** export option bundles (enabled by default). If you'd rather not ship them, turn that option off and upload the portable PDBs to Sentry with `sentry-cli` instead, the same way as for Android (below).

- **Android:** Upload the portable PDB files for your managed assemblies. The SDK reads the packed assemblies on the device automatically, so you don't need to recompile export templates for managed frames — only the PDB upload is required.

After exporting, Godot writes the assemblies and their `.pdb` companions under `.godot/mono/temp/bin/`. Point the command at that directory, and the CLI scans it recursively, picking up every architecture and export profile:

```bash {tabTitle:Bash/PowerShell}
sentry-cli debug-files upload --type portablepdb --org ___ORG_SLUG___ --project ___PROJECT_SLUG___ .godot/mono/temp/bin
```

- **iOS:** Godot compiles C# ahead of time (NativeAOT) on iOS, so managed frames are part of the native binary. Upload the dSYM debug symbols produced by the export:

```bash {tabTitle:Bash/PowerShell}
sentry-cli debug-files upload --type dsym --org ___ORG_SLUG___ --project ___PROJECT_SLUG___ <exported-directory>
```

As with native iOS symbols, export your project to a directory first, then run the upload against that directory.

- **Web:** Godot 4.x doesn't support C# in web exports, so managed symbolication doesn't apply to the Web platform.

## Known Limitations

### Web (WASM)
Expand Down
15 changes: 14 additions & 1 deletion docs/platforms/godot/data-management/data-collected.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ By default, the Sentry SDK doesn't send any information about users, such as ema

You can also set user information from code:

```GDScript
```gdscript {tabTitle:GDScript} {mdExpandTabs}
var user := SentryUser.new()
user.id = "custom_id"
user.email = "bob@example.com"
Expand All @@ -23,6 +23,19 @@ user.ip_address = "127.0.0.1"
SentrySDK.set_user(user)
```

```csharp {tabTitle:C#}
SentrySdk.ConfigureScope(scope =>
{
scope.User = new SentryUser
{
Id = "custom_id",
Email = "bob@example.com",
Username = "bob",
IpAddress = "127.0.0.1",
};
});
```

## Device Information

The Sentry SDK collects information about the device, such as the name, version and build of your operating system or Linux distribution. This information is sent to Sentry by default.
Expand Down
140 changes: 140 additions & 0 deletions docs/platforms/godot/dotnet/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
title: C#/.NET Support
sidebar_title: C#/.NET
sidebar_order: 15
description: "Learn how to capture errors from your Godot game's C# (.NET) code with Sentry."
---

The SDK for Godot Engine can capture errors from your game's C# code, in addition to GDScript and the engine itself. C# support is available in version 2.0.0 and later.

The SDK runs two layers side by side: the **native layer**, which reports GDScript and engine errors, and a **.NET layer**, which reports C# errors. You configure Sentry once, and your options, scope, and trace stay synchronized across both layers automatically. See [How the two layers work together](#how-the-two-layers-work-together) for what this means in practice.

## Prerequisites

- The **.NET build** of Godot Engine 4.5 or later. C# isn't available in the standard build.
- A project with C# enabled. Godot generates a `.csproj` file when you add your first C# script.
- C# error reporting is supported on **desktop** (Windows, Linux, and macOS), **Android**, and **iOS**. Godot doesn't support C# in web exports.

## Install

The Sentry addon already ships the .NET libraries in `addons/sentry/dotnet/`. When you open your project in the editor, the SDK adds an import to your `.csproj` that wires them in:

```xml {filename:YourGame.csproj}
<Import Project="addons/sentry/dotnet/Sentry.Godot.props" Condition="Exists('addons/sentry/dotnet/Sentry.Godot.props')" />
```

This references the `Sentry` NuGet package, the `Sentry.Godot.dll` wrapper, and a Roslyn analyzer that guides you toward the correct API (see [Use the SDK in C#](#use-the-sdk-in-c)). Build your project (for example, with the editor's **Build** button) to restore the NuGet package.

<Alert>

If the import isn't added the first time, restart the Godot editor.

</Alert>

## Configure

Set your [DSN](/product/sentry-basics/dsn-explainer/) in **Project Settings > Sentry > Options**. With **Auto Init** enabled (the default), both the native and .NET layers initialize automatically when your game starts, so there's nothing else to do.

### Manual Initialization

If you need to set options from code — for example, to define a [`before_send`](/platforms/godot/configuration/options/#before_send) callback — disable **Auto Init** in **Project Settings > Sentry > Options** and initialize the SDK from C# code. See [Programmatic Configuration](/platforms/godot/configuration/options/#programmatic-configuration) for a complete C# example.

Initializing Sentry from either language brings up both layers, so a single `Init()` call is all you need — there's no need to initialize it separately in C# and GDScript.

Options come from `SentryGodotOptions`, which extends the .NET SDK's `SentryOptions` with Godot-specific settings such as `AttachLog`, `AttachSceneTree`, and `AttachScreenshot`. Shared options like the DSN, release, environment, and sample rate default to the values from your Project Settings, so you only need to set what you want to override.

## Verify

Throw an exception from any C# script to confirm that reporting works:

```csharp
using Godot;
using System;

public partial class SentryTest : Node
{
public override void _Ready()
{
throw new Exception("Hello from Sentry .NET!");
}
}
```

The SDK captures unhandled exceptions from your C# code automatically.

## Use the SDK in C#

Make your Sentry calls through `Sentry.Godot.SentrySdk`. The addon ships a global alias, so it resolves to the Godot wrapper automatically, even alongside `using Sentry;`:

```csharp
SentrySdk.CaptureMessage("Something went wrong");
```

<Alert level="warning" title="Use the Godot wrapper">

Don't call `Sentry.SentrySdk` (the upstream .NET SDK) directly. It skips Godot-specific initialization and options. The bundled analyzer flags this with a warning (`SENTRYGD1001`) and offers a one-click fix.

</Alert>

`SentrySdk` exposes the full Sentry .NET SDK API. Here are a few common operations.

### Capture an Exception

Unhandled exceptions are captured automatically. To capture a handled one:

```csharp
try
{
ProcessSave();
}
catch (Exception ex)
{
SentrySdk.CaptureException(ex);
}
```

### Add a Breadcrumb

```csharp
SentrySdk.AddBreadcrumb("Player respawned", category: "gameplay");
```

### Set the User and Tags

There's no `SetUser` method on the SDK — configure the user through the scope instead:

```csharp
SentrySdk.SetTag("biome", "jungle");

SentrySdk.ConfigureScope(scope =>
{
scope.User = new SentryUser
{
Id = "12345",
Username = "Jane",
};
});
```

## How the Two Layers Work Together

The native and .NET layers keep their state in sync, so you configure Sentry once and both report consistent data.

- **Options are synchronized.** The DSN, release, environment, sample rate, and other shared options apply to both layers, so you only need to set them once — in Project Settings, or in a C# or GDScript init callback.
- **Scope syncs both ways.** Tags, breadcrumbs, and the user you set in GDScript appear on C# events, and the ones you set in C# appear on GDScript and engine events. There's no need to set them twice.
- **Events share a trace.** C# and GDScript events from the same session are linked, so you can follow an issue across both languages.
- **Default attachments carry over.** The log file, screenshot, and scene tree attachments you've enabled are included on C# events too.
- **Sessions are tracked once.** [Release Health](/platforms/godot/configuration/releases/#release-health) is handled for the whole game automatically. Don't enable session tracking in C# — it would double-count sessions.

## Readable Stack Traces

Getting file names and line numbers for C# stack frames depends on the platform: on desktop, the SDK resolves them at runtime from the debug symbols shipped with your game; on Android and iOS, you upload debug symbols to Sentry. See [Readable Stack Traces](/platforms/godot/configuration/stack-traces/#c-managed-code) for the details.

## Limitations

C# support has the following limitations:

- Custom contexts and user-added attachments aren't synced between the native and .NET layers. They appear only on events captured by the layer that set them. Tags, breadcrumbs, and the user are synced.
- The error throttling [limits](/platforms/godot/configuration/options/#logger_limits) apply to GDScript and engine errors only, not to C# exceptions.
- On mobile, C# events currently report the wrong operating system — `Linux` on Android and `Darwin` on iOS — instead of `Android` or `iOS`.
- On Android, C# exceptions can't be captured while the Godot debugger is attached to the app. The debugger attaches when you deploy to a device from the editor with **Debug > Deploy with Remote Debug** enabled (the default). Turn that menu option off, or test with an exported build, to capture them.
10 changes: 7 additions & 3 deletions docs/platforms/godot/enriching-events/attachments/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The filename is the name of the file to display in Sentry. When using bytes you

The specific media content type that determines how the attachment is rendered in the Sentry UI. Any [MIME type](https://www.iana.org/assignments/media-types/media-types.xhtml) may be used; the default is `application/octet-stream`.

We currently support and can render the following MIME types:
We currently support and can render the following MIME types:

- `text/plain`
- `text/css`
Expand All @@ -49,7 +49,7 @@ You can add attachments that will be sent with every event using <PlatformIdenti

<PlatformContent includePath="enriching-events/attachment-upload" />

You can also add attachments inside the `SentrySDK.init()` configuration callback. This is useful when you want to register attachments as part of SDK setup:
In GDScript, you can also add attachments inside the `SentrySDK.init()` configuration callback. This is useful when you want to register attachments as part of SDK setup:

```GDScript
SentrySDK.init(func(options: SentryOptions) -> void:
Expand All @@ -62,10 +62,14 @@ SentrySDK.init(func(options: SentryOptions) -> void:

To clear all user-added attachments, use <PlatformIdentifier name="SentrySDK.clear-attachments()" />. Built-in attachments such as log files, screenshots, and view hierarchy are preserved.

```GDScript
```gdscript {tabTitle:GDScript} {mdExpandTabs}
SentrySDK.clear_attachments()
```

```csharp {tabTitle:C#}
SentrySdk.ConfigureScope(scope => scope.ClearAttachments());
```

<Alert>

Sentry allows at most 40MB for a compressed request, and at most 200MB of uncompressed attachments per event, including the crash report file (if applicable). Uploads exceeding this size are rejected with HTTP error `413 Payload Too Large` and the data is dropped immediately. To add larger or more files, consider secondary storage options.
Expand Down
Loading
Loading