Exceptions
Exceptions happen.
Spectre.Console.Cli
handles exceptions, writes a user friendly message to the console and sets the exitCode
of the application to -1
.
While this might be enough for the needs of most applications, there are some options to customize this behavior.
Propagating exceptions
The most basic way is to set PropagateExceptions()
during configuration and handle everything.
While this option grants the most freedom, it also requires the most work: Setting PropagateExceptions
means that Spectre.Console.Cli
effectively re-throws exceptions.
This means that app.Run()
should be wrapped in a try
-catch
-block which has to handle the exception
(i.e. outputting something useful) and also provide the exitCode (or return
value) for the application.
using Spectre.Console.Cli;
namespace MyApp
{
public static class Program
{
public static int Main(string[] args)
{
var app = new CommandApp<FileSizeCommand>();
app.Configure(config =>
{
config.PropagateExceptions();
});
try
{
return app.Run(args);
}
catch (Exception ex)
{
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything);
return -99;
}
}
}
}
Using a custom ExceptionHandler
Using the SetExceptionHandler()
during configuration it is possible to handle exceptions in a defined way.
This method comes in two flavours: One that uses the default exitCode (or return
value) of -1
and one
where the exitCode needs to be supplied.
The ITypeResolver?
parameter will be null, when the exception occurs while no ITypeResolver
is available.
(Basically the ITypeResolver
will be set, when the exception occurs during a command execution, but not
during the parsing phase and construction of the command.)
Using SetExceptionHandler(Func<Exception, ITypeResolver?, int> handler)
Using this method exceptions can be handled in a custom way. The return value of the handler is used as the exitCode for the application.
using Spectre.Console.Cli;
namespace MyApp
{
public static class Program
{
public static int Main(string[] args)
{
var app = new CommandApp<FileSizeCommand>();
app.Configure(config =>
{
config.SetExceptionHandler((ex, resolver) =>
{
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything);
return -99;
});
});
return app.Run(args);
}
}
}
Using SetExceptionHandler(Action<Exception, ITypeResolver?> handler)
Using this method exceptions can be handled in a custom way, much the same as with the SetExceptionHandler(Func<Exception, ITypeResolver?, int> handler)
.
Using the Action
as the handler however, it is not possible (or required) to supply a return value.
The exitCode for the application will be -1
.
using Spectre.Console.Cli;
namespace MyApp
{
public static class Program
{
public static int Main(string[] args)
{
var app = new CommandApp<FileSizeCommand>();
app.Configure(config =>
{
config.SetExceptionHandler((ex, resolver) =>
{
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything);
});
});
return app.Run(args);
}
}
}