Skip to content

GH2153: Fix async stack traces rendering as MoveNext() instead of source methods#2154

Merged
patriksvensson merged 1 commit into
spectreconsole:mainfrom
devlead:feature/gh-2153
Jun 18, 2026
Merged

GH2153: Fix async stack traces rendering as MoveNext() instead of source methods#2154
patriksvensson merged 1 commit into
spectreconsole:mainfrom
devlead:feature/gh-2153

Conversation

@devlead

@devlead devlead commented Jun 18, 2026

Copy link
Copy Markdown
Contributor
  • I have read the Contribution Guidelines
  • I have checked that there isn't already another pull request that solves the above issue
  • All newly added code is adequately covered by tests
  • All existing tests are still running without errors

Changes

Async exception stack frames were showing async void MoveNext() because TryResolveStateMachineMethod took MethodBase by value. The resolved method (e.g. ExecuteAsync) was assigned to a local copy and never propagated back to the caller, matching .NET StackTrace behavior only partially.

Example

catch(Exception exception)
{
    AnsiConsole.WriteException(
        exception,
        ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks
    );
}

Before fix (broken — MethodBase passed by value)

InvalidOperationException: Throwing async!
  at async void MoveNext() in Exceptions.cs:100
  at void ThrowFromAsync() in Exceptions.cs:200
  at Exception GetException(Action action) in ExceptionTests.cs:300

After fix (ref MethodBase — matches .NET StackTrace)

InvalidOperationException: Throwing async!
  at async Task MethodThatThrowsAsync() in Exceptions.cs:100
  at void ThrowFromAsync() in Exceptions.cs:200
  at Exception GetException(Action action) in ExceptionTests.cs:300

Please upvote 👍 this pull request if you are interested in it.

…) instead of source methods

Async exception stack frames were showing `async void MoveNext()` because
`TryResolveStateMachineMethod` took `MethodBase` by value. The resolved
method (e.g. `ExecuteAsync`) was assigned to a local copy and never
propagated back to the caller, matching .NET StackTrace behavior only
partially.

- Pass `MethodBase` by ref in `TryResolveStateMachineMethod` and at its call site in `GetMethodName`
- Add async throw helpers to `TestExceptions` for regression coverage
- Add verifier test and snapshot asserting resolved async method names
- Fixes spectreconsole#2153
@patriksvensson patriksvensson merged commit a0913f8 into spectreconsole:main Jun 18, 2026
3 checks passed
@patriksvensson

Copy link
Copy Markdown
Contributor

Merged! Thank you for your contribution. Much appreciated! 👍

This was referenced Jun 24, 2026
This was referenced Jun 29, 2026
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.

ExceptionRenderableBuilder shows async state machine methods (i.e. MoveNext)

2 participants