Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
35 changes: 35 additions & 0 deletions src/docfx/Extensions/SpectreConsoleExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Spectre.Console;
using Spectre.Console.Cli;

namespace Docfx;

internal static class SpectreConsoleExtensions
{
public static void WriteException(this IAnsiConsole ansiConsole, Exception e)
{
if (e is CommandAppException cae)
{
if (cae.Pretty is { } pretty)
AnsiConsole.Write(pretty);
else
AnsiConsole.MarkupInterpolated($"[red]Error:[/] {e.Message}");
return;
}
else
{
AnsiConsole.WriteException(e, new ExceptionSettings()
{
Format = ExceptionFormats.ShortenEverything,
Style = new()
{
ParameterName = Color.Grey,
ParameterType = Color.Grey78,
LineNumber = Color.Grey78,
},
});
}
}
}
39 changes: 24 additions & 15 deletions src/docfx/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Docfx.Common;
using Spectre.Console;
using Spectre.Console.Cli;

Expand Down Expand Up @@ -39,26 +40,34 @@ internal static int Main(string[] args)

static void OnException(Exception e, ITypeResolver? resolver)
{
if (e is CommandAppException cae)
// Try to unwrap AggregateException.
if (e is AggregateException ae && ae.InnerExceptions.Count == 1)
e = ae.InnerExceptions[0];

if (!Console.IsOutputRedirected)
{
if (cae.Pretty is { } pretty)
AnsiConsole.Write(pretty);
else
AnsiConsole.MarkupInterpolated($"[red]Error:[/] {e.Message}");
// Write exception to console.
AnsiConsole.Console.WriteException(e);

// Write exception to ReportLogListener if exists.
var reportLogListener = Logger.FindListener(x => x is ReportLogListener);
reportLogListener?.WriteLine(Logger.GetLogItem(LogLevel.Error, e.ToString(), code: ErrorCodes.Build.FatalError));
}
else
{
AnsiConsole.WriteException(e, new ExceptionSettings()
{
Format = ExceptionFormats.ShortenEverything,
Style = new()
{
ParameterName = Color.Grey,
ParameterType = Color.Grey78,
LineNumber = Color.Grey78,
},
});
// Write exception with Logger API if stdout is redirected.
// To avoid line wrap issue https://github.com/spectreconsole/spectre.console/issues/1782
var exceptions = e is AggregateException ae2
? ae2.Flatten().InnerExceptions.ToArray()
: [e];

foreach (var ex in exceptions)
Logger.LogError(e.ToString(), code: ErrorCodes.Build.FatalError);
}

// Cleanup logger.
Logger.Flush();
Logger.UnregisterAllListeners();
}
}
}
13 changes: 11 additions & 2 deletions test/docfx.Tests/CommandLineTest.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Docfx.Common;

namespace Docfx.Tests;

[Collection("docfx STA")]
public static class CommandLineTest
public class CommandLineTest
{
[Fact]
public static void PrintsVersion()
Expand All @@ -31,7 +33,14 @@ public static void PrintsHelp()
[Fact]
public static void FailForUnknownArgs()
{
Assert.Equal(-1, Program.Main(["--unknown"]));
try
{
Assert.Equal(-1, Program.Main(["--unknown"]));
}
finally
{
Logger.ResetCount();
}
}

[Fact]
Expand Down