diff --git a/src/Spectre.Console.Tests/Data/Exceptions.cs b/src/Spectre.Console.Tests/Data/Exceptions.cs index ec4f704c3..5e10304a1 100644 --- a/src/Spectre.Console.Tests/Data/Exceptions.cs +++ b/src/Spectre.Console.Tests/Data/Exceptions.cs @@ -43,6 +43,15 @@ public static (string Key, List Values) GetTuplesWithInnerException((int F MethodThatThrows(0); return ("key", []); } + + public static async Task MethodThatThrowsAsync() + { + await Task.Yield(); + throw new InvalidOperationException("Throwing async!"); + } + + public static void ThrowFromAsync() => + MethodThatThrowsAsync().GetAwaiter().GetResult(); } #pragma warning disable CS9113 // Parameter is unread. diff --git a/src/Spectre.Console.Tests/Expectations/Exception/AsyncStackTrace.Output.verified.txt b/src/Spectre.Console.Tests/Expectations/Exception/AsyncStackTrace.Output.verified.txt new file mode 100644 index 000000000..a0b68b3b9 --- /dev/null +++ b/src/Spectre.Console.Tests/Expectations/Exception/AsyncStackTrace.Output.verified.txt @@ -0,0 +1,4 @@ +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 diff --git a/src/Spectre.Console.Tests/Unit/ExceptionTests.cs b/src/Spectre.Console.Tests/Unit/ExceptionTests.cs index 62aea7b39..9653cf0d5 100644 --- a/src/Spectre.Console.Tests/Unit/ExceptionTests.cs +++ b/src/Spectre.Console.Tests/Unit/ExceptionTests.cs @@ -222,6 +222,25 @@ public Task Exception_Within_Expanded_Panel_Should_Expand_As_Expected() return Verifier.Verify(console.Output); } + [Fact] + [Expectation("AsyncStackTrace")] + public Task Should_Write_Async_Exception_With_Resolved_Method_Names() + { + // Given + var console = new TestConsole().Width(1024); + var dex = GetException(TestExceptions.ThrowFromAsync); + + // When + console.WriteException(dex, new ExceptionSettings + { + Format = ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks, + Resolver = new ExceptionScrubber(), + }); + + // Then + return Verifier.Verify(console.Output); + } + private static Exception GetException(Action action) { try diff --git a/src/Spectre.Console/Widgets/Exceptions/ExceptionRenderableBuilder.cs b/src/Spectre.Console/Widgets/Exceptions/ExceptionRenderableBuilder.cs index 58d18c803..c71214c32 100644 --- a/src/Spectre.Console/Widgets/Exceptions/ExceptionRenderableBuilder.cs +++ b/src/Spectre.Console/Widgets/Exceptions/ExceptionRenderableBuilder.cs @@ -292,7 +292,7 @@ private static string GetMethodName(ExceptionInfoResolver resolver, ref MethodBa isAsync = typeof(IAsyncStateMachine).IsAssignableFrom(declaringType); if (isAsync || typeof(IEnumerator).IsAssignableFrom(declaringType)) { - TryResolveStateMachineMethod(method, out declaringType); + TryResolveStateMachineMethod(ref method, out declaringType); } } else @@ -304,7 +304,7 @@ private static string GetMethodName(ExceptionInfoResolver resolver, ref MethodBa } [RequiresDynamicCode(ExceptionRenderableBuilder.AotWarning)] - private static bool TryResolveStateMachineMethod(MethodBase method, out Type declaringType) + private static bool TryResolveStateMachineMethod(ref MethodBase method, out Type declaringType) { // https://github.com/dotnet/runtime/blob/v6.0.0/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs#L400-L455 declaringType = method.DeclaringType ??