Skip to content

Commit b2689be

Browse files
phil-scott-78patriksvensson
authored andcommitted
Enhance ExceptionFormatter for AOT compatibility by adding fallback handling for stack frames.
1 parent 835143d commit b2689be

File tree

1 file changed

+28
-11
lines changed

1 file changed

+28
-11
lines changed

src/Spectre.Console/Widgets/Exceptions/ExceptionFormatter.cs

+28-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
namespace Spectre.Console;
22

33
// ExceptionFormatter relies heavily on reflection of types unknown until runtime.
4-
// We'll suppress these warnings, but alert the user this method is not supported.
54
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode")]
65
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2070:RequiresUnreferencedCode")]
76
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2075:RequiresUnreferencedCode")]
8-
[RequiresDynamicCode(AotWarning)]
7+
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL3050:RequiresUnreferencedCode")]
98
internal static class ExceptionFormatter
109
{
1110
public const string AotWarning = "ExceptionFormatter is currently not supported for AOT.";
@@ -27,13 +26,6 @@ private static IRenderable GetException(Exception exception, ExceptionSettings s
2726
throw new ArgumentNullException(nameof(exception));
2827
}
2928

30-
// fallback to default ToString() if someone in an AOT is insisting on using this method
31-
var stackTrace = new StackTrace(exception, fNeedFileInfo: false);
32-
if (stackTrace.GetFrame(0)?.GetMethod() is null)
33-
{
34-
return new Text(exception.ToString());
35-
}
36-
3729
return new Rows(GetMessage(exception, settings), GetStackFrames(exception, settings)).Expand();
3830
}
3931

@@ -71,8 +63,16 @@ private static Grid GetStackFrames(Exception ex, ExceptionSettings settings)
7163
}
7264

7365
var stackTrace = new StackTrace(ex, fNeedFileInfo: true);
74-
var frames = stackTrace
75-
.GetFrames()
66+
var allFrames = stackTrace.GetFrames();
67+
if (allFrames[0]?.GetMethod() == null)
68+
{
69+
// if we can't easily get the method for the frame, then we are in AOT
70+
// fallback to using ToString method of each frame.
71+
WriteAotFrames(grid, stackTrace.GetFrames(), styles);
72+
return grid;
73+
}
74+
75+
var frames = allFrames
7676
.FilterStackFrames()
7777
.ToList();
7878

@@ -133,6 +133,23 @@ private static Grid GetStackFrames(Exception ex, ExceptionSettings settings)
133133
return grid;
134134
}
135135

136+
private static void WriteAotFrames(Grid grid, StackFrame?[] frames, ExceptionStyle styles)
137+
{
138+
foreach (var stackFrame in frames)
139+
{
140+
if (stackFrame == null)
141+
{
142+
continue;
143+
}
144+
145+
var s = stackFrame.ToString();
146+
s = s.Replace(" in file:line:column <filename unknown>:0:0", string.Empty).TrimEnd();
147+
grid.AddRow(
148+
$"[{styles.Dimmed.ToMarkup()}]at[/]",
149+
s.EscapeMarkup());
150+
}
151+
}
152+
136153
private static void AppendParameters(StringBuilder builder, MethodBase? method, ExceptionSettings settings)
137154
{
138155
var typeColor = settings.Style.ParameterType.ToMarkup();

0 commit comments

Comments
 (0)