diff --git a/app.go b/app.go index 0be004d..83a081e 100644 --- a/app.go +++ b/app.go @@ -14,10 +14,17 @@ var ErrNoRootCommand = errors.New("no root command provided") // App represents a command line application. type App struct { CobraProvider + ErrorHandler Exit func(code int) root *cobra.Command } +// ErrorHandler is a function that will be used to handle the errors. The +// function will be called regardless if an error has been received, so proper +// error checking is required. If true is returned, the default error handling +// will not be used. +type ErrorHandler func(err error) bool + // CobraProvider is used to provide a Cobra command. type CobraProvider interface { Command() *cobra.Command @@ -33,8 +40,13 @@ func New(cp CobraProvider) *App { // ExecuteOrDie will execute the application or perform os.Exit in case of error. func (a *App) ExecuteOrDie(options ...Option) { - if err := a.Execute(options...); err != nil { - a.Exit(retcode.Calc(err)) + err := a.Execute(options...) + if a.ErrorHandler == nil { + a.defaultErrorHandler(err) + return + } + if !a.ErrorHandler(err) { + a.defaultErrorHandler(err) } } @@ -64,3 +76,9 @@ func (a *App) init() error { } return nil } + +func (a *App) defaultErrorHandler(err error) { + if err != nil { + a.Exit(retcode.Calc(err)) + } +} diff --git a/app_test.go b/app_test.go index b6db0d6..e079251 100644 --- a/app_test.go +++ b/app_test.go @@ -14,6 +14,7 @@ import ( func TestExecuteOrDie(t *testing.T) { var buf bytes.Buffer var retcode int + var err error commandline.New(new(testApp)).ExecuteOrDie( commandline.WithCommand(func(cmd *cobra.Command) { cmd.SetOut(&buf) @@ -23,9 +24,14 @@ func TestExecuteOrDie(t *testing.T) { commandline.WithExit(func(code int) { retcode = code }), + commandline.WithErrorHandler(func(merr error) bool { + err = merr + return false + }), ) assert.Equal(t, `example Input: ["arg1" "arg2"]`, buf.String()) assert.Equal(t, 133, retcode) + assert.Assert(t, err != nil) } func TestExit(t *testing.T) { diff --git a/options.go b/options.go index a34cbd6..9ede19a 100644 --- a/options.go +++ b/options.go @@ -41,6 +41,13 @@ func WithCommand(fn func(cmd *cobra.Command)) Option { } } +// WithErrorHandler will allow changing the default error handler. +func WithErrorHandler(fn ErrorHandler) Option { + return func(app *App) { + app.ErrorHandler = fn + } +} + // WithExit creates an option which sets the exit function. func WithExit(fn func(code int)) Option { return func(app *App) {