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 SetErrorHandler() 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.

Using SetErrorHandler(Func<Exception, 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 =>
                {
                    AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything);
                    return -99;
                });
            });

            return app.Run(args);
        }
    }
}

Using SetErrorHandler(Action<Exception> handler)

Using this method exceptions can be handled in a custom way, much the same as with the SetErrorHandler(Func<Exception, 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 =>
                {
                    AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything);
                });
            });

            return app.Run(args);
        }
    }
}