Skip to content

Improve Unity WebGL handling for stackless Unity log-callback exception reports.#282

Merged
melekr merged 44 commits intomasterfrom
feature/stackless_log_exceptions
May 8, 2026
Merged

Improve Unity WebGL handling for stackless Unity log-callback exception reports.#282
melekr merged 44 commits intomasterfrom
feature/stackless_log_exceptions

Conversation

@melekr
Copy link
Copy Markdown
Collaborator

@melekr melekr commented Apr 29, 2026

Summary

Improve Unity WebGL handling for stackless Unity log-callback exception reports.

This change adds diagnostics for reports where Unity supplies an Error or Exception log message but an empty stackTrace string through Application.logMessageReceived or Application.logMessageReceivedThreaded.

It also adds WebGL-default observation of original exceptions passed through Debug.LogException(exception) by wrapping Debug.unityLogger.logHandler.

The log handler does not send reports directly. It records the original exception as a short-lived candidate, forwards to Unity's original/custom log handler, and waits for Unity's log callback. The Unity log callback remains the single send trigger.

When the Unity callback returns, the SDK chooses the best available stack source:

  1. Original exception stack trace, if present and parseable.
  2. Unity callback stackTrace, if present and parseable.
  3. No frames, with explicit stackless diagnostics, if neither source is usable.

Problem

Some Unity WebGL reports arrive with an exception message but no stack frames.
The raw payload has an empty exception stackTrace and an empty thread stack, so there are no frames for the server or UI to symbolize.

The existing Unity log-callback path builds reports from:

  • message
  • stackTrace
  • LogType

Unity does not provide the original Exception object through Application.logMessageReceived.

This made stackless WebGL events difficult to triage because the report did not clearly explain whether the SDK received an empty Unity callback stack, recovered an original exception stack, or had no usable stack source.

Changes

  • Add capture-path diagnostics for Unity log-callback reports:

    • backtrace.unity.capture_path
    • backtrace.unity.log.type
    • backtrace.unity.log.stacktrace.empty
    • backtrace.unity.log.stacktrace.length
    • backtrace.unity.log.message.length
    • backtrace.unity.log.thread.id
    • backtrace.unity.log.thread.is_main
    • backtrace.unity.stacktrace_log_type.error
    • backtrace.unity.stacktrace_log_type.exception
    • backtrace.unity.stack_source
    • backtrace.unity.report.frames.empty
    • backtrace.unity.stackless.reason
  • Add WebGL-default Debug.unityLogger.logHandler exception observation:

    • records original Exception objects passed through Debug.LogException
    • forwards to the previous Unity/custom log handler
    • waits for Unity’s later log callback before sending
    • avoids duplicate reports
    • preserves original exception type, stack presence, context name, and thread id
  • Add internal no-environment-fallback stack construction for SDK-owned Unity log-callback reports so stackless original exceptions do not create SDK capture-time frames.

  • Preserve recent Unity log/source context even when a report has zero frames.

  • Preserve enriched BacktraceReport attributes and annotations through background-thread queueing.

  • Make background log handling and log-manager access thread-safe.

  • Add internal report annotations:

    • Unity log capture
    • Unity log handler exception
    • WebGL JavaScript stack at capture
  • Add optional WebGL JavaScript stack-at-capture annotation, disabled by default.

What this does not do

This does not synthesize managed C# stack frames when Unity provides neither a callback stack nor an original exception object with a usable stack.

If Unity supplies stackTrace == "" and the original exception object is unavailable or stackless, Backtrace records that fact and preserves the best available context.

Tests

  • Runtime tests for Unity log diagnostics.
  • Runtime tests for original exception metadata and candidate matching.
  • Runtime tests for no-environment-fallback stack behavior.
  • Runtime tests for stack-source selection:
    • original exception stack
    • Unity callback stack
    • unavailable / stackless
    • original exception stack present but unparsed
  • Runtime tests for custom annotation serialization.
  • Runtime tests for source/log context preservation on zero-frame reports.
  • Runtime tests for candidate thread-id preservation.

ref : BT-6857

@melekr melekr changed the title Feature/stackless log exceptions Improve Unity WebGL handling for stackless Unity log-callback exception reports. Apr 29, 2026
@melekr melekr self-assigned this Apr 29, 2026
@melekr
Copy link
Copy Markdown
Collaborator Author

melekr commented Apr 29, 2026

can be improved to not send directly from BacktraceUnityLogHandler / TryCaptureUnityLogHandlerException, directly constructing BacktraceReport(exception) from ILogHandler can be misleading for stackless original exceptions.

BacktraceStackTrace currently falls back to the SDK capture-time environment stack when new StackTrace(exception, true) has no frames. That can turn Debug.LogException(new ArgumentNullException("obj")) into a report with misleading faulting SDK frames.

@melekr
Copy link
Copy Markdown
Collaborator Author

melekr commented Apr 29, 2026

Addressables integration is a great feature but is better suited for a subsequent PR.

melekr added 18 commits April 29, 2026 14:02
Add factory tests for stack-source
Update source-code flow tests for stackless and frame bearing paths
Restrict candidate prefixes to type+message
Fall back to type only when empty
Filter capture-path by prefix and fall back to log type
Update Test case to assert reports with recovered frames drop stackless reason
…stack is empty

Update Test case to cover original exception unparsed-stack diagnostic
Pass thread id to helper tests and assert it
Add Test case for candidate thread id propagation for background-thread captures
@melekr melekr marked this pull request as ready for review May 8, 2026 13:37
@melekr melekr merged commit 23e43b7 into master May 8, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant