Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
- The SDK no longer ends sessions as crashed when capturing unhandled or logged exceptions. Instead, sessions get correctly marked as `SessionEndStatus.Unhandled` ([#2376](https://github.com/getsentry/sentry-unity/pull/2376))
- Added support for Structured Logging. The `SentrySdk.Logger` API is now exposed for Unity users, enabling structured log capture. The SDK can also automatically capture and send Debug logs based on the options configured. ([#2368](https://github.com/getsentry/sentry-unity/pull/2368))

### Fixes

- When configured, the SDK now no longer treats `Debug.LogError` events as exceptions but resports them as message events instead ([#2377](https://github.com/getsentry/sentry-unity/pull/2377))

### Dependencies

- Bump CLI from v2.56.0 to v2.56.1 ([#2356](https://github.com/getsentry/sentry-unity/pull/2356))
Expand Down
7 changes: 0 additions & 7 deletions src/Sentry.Unity/Il2CppEventProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ public void Process(Exception incomingException, SentryEvent sentryEvent)
{
Options.DiagnosticLogger?.LogDebug("Running Unity IL2CPP event exception processor on: Event {0}", sentryEvent.EventId);

// UnityLogException is a synthetic exception created by the LoggingIntegration by parsing the stacktrace provided
// to the SDK as a string. It therefore lacks the necessary data to fetch the native stacktrace and go from there
if (incomingException is UnityErrorLogException)
{
return;
}

var sentryExceptions = sentryEvent.SentryExceptions;
if (sentryExceptions == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ private bool IsGettingDebounced(LogType logType)
private void ProcessException(string message, string stacktrace, LogType logType)
{
// LogType.Exception is getting handled by the `UnityLogHandlerIntegration`
// UNLESS we're configured to handle them - i.e. on WebGL
// UNLESS we're configured to process them - i.e. on WebGL
if (logType is LogType.Exception && _captureExceptions)
{
_options.LogDebug("Exception capture has been enabled. Capturing exception through '{0}'.", nameof(UnityApplicationLoggingIntegration));

var ule = new UnityErrorLogException(message, stacktrace, _options);
_hub?.CaptureException(ule);
var evt = UnityLogEventFactory.CreateExceptionEvent(message, stacktrace, _options);
_hub?.CaptureEvent(evt);
}
}

Expand All @@ -107,12 +107,8 @@ private void ProcessError(string message, string stacktrace, LogType logType)

if (_options.AttachStacktrace && !string.IsNullOrEmpty(stacktrace))
{
_options.LogDebug("Attaching stacktrace to event.");

var ule = new UnityErrorLogException(message, stacktrace, _options);
var sentryEvent = new SentryEvent(ule) { Level = SentryLevel.Error };

_hub?.CaptureEvent(sentryEvent);
var evt = UnityLogEventFactory.CreateMessageEvent(message, stacktrace, SentryLevel.Error, _options);
_hub?.CaptureEvent(evt);
}
else
{
Expand Down
173 changes: 0 additions & 173 deletions src/Sentry.Unity/Integrations/UnityErrorLogException.cs

This file was deleted.

94 changes: 94 additions & 0 deletions src/Sentry.Unity/Integrations/UnityLogEventFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Sentry.Protocol;

namespace Sentry.Unity.Integrations;

/// <summary>
/// Factory for creating SentryEvent objects from Unity log messages and stacktraces
/// </summary>
internal static class UnityLogEventFactory
{
/// <summary>
/// Creates a message event with stacktrace attached via threads (for Debug.LogError)
/// </summary>
/// <param name="message">The log message</param>
/// <param name="stackTrace">The Unity stacktrace string</param>
/// <param name="level">The Sentry event level</param>
/// <param name="options">Sentry Unity options</param>
/// <returns>A SentryEvent with the message and stacktrace as threads</returns>
public static SentryEvent CreateMessageEvent(
string message,
string stackTrace,
SentryLevel level,
SentryUnityOptions options)
{
var frames = UnityStackTraceParser.Parse(stackTrace, options);
frames.Reverse();

var thread = CreateThreadFromStackTrace(frames);

return new SentryEvent
{
Message = message,
Level = level,
SentryThreads = [thread]
};
}

/// <summary>
/// Creates an exception event from Unity log data (for exceptions on WebGL)
/// </summary>
/// <param name="message">The log message</param>
/// <param name="stackTrace">The Unity stacktrace string</param>
/// <param name="options">Sentry Unity options</param>
/// <returns>A SentryEvent with a synthetic exception</returns>
public static SentryEvent CreateExceptionEvent(
string message,
string stackTrace,
SentryUnityOptions options)
{
var frames = UnityStackTraceParser.Parse(stackTrace, options);
frames.Reverse();

var sentryException = CreateUnityLogException(message, frames);

return new SentryEvent(new Exception(message))
{
SentryExceptions = [sentryException],
Level = SentryLevel.Error
};
}

private static SentryThread CreateThreadFromStackTrace(List<SentryStackFrame> frames)
{
var currentThread = Thread.CurrentThread;
return new SentryThread
{
Crashed = false,
Current = true,
Name = currentThread.Name,
Id = currentThread.ManagedThreadId,
Stacktrace = new SentryStackTrace { Frames = frames }
};
}

private static SentryException CreateUnityLogException(
string message,
List<SentryStackFrame> frames,
string exceptionType = "LogError")
{
return new SentryException
{
Stacktrace = new SentryStackTrace { Frames = frames },
Value = message,
Type = exceptionType,
Mechanism = new Mechanism
{
Handled = true,
Type = "unity.log"
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Bug

The Mechanism created in CreateUnityLogException omits the Synthetic = true flag and Data = { { Mechanism.TerminalKey, false } } properties. Previously present, these are crucial for correctly categorizing synthetic exceptions, especially for WebGL events processed via CreateExceptionEvent, potentially affecting Sentry's processing.

Fix in Cursor Fix in Web

}
}
Loading
Loading