Skip to content

Commit

Permalink
Custom error handler
Browse files Browse the repository at this point in the history
  • Loading branch information
cardil committed Oct 18, 2024
1 parent 24d49d4 commit b881b94
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
22 changes: 20 additions & 2 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
}

Expand Down Expand Up @@ -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))
}
}
6 changes: 6 additions & 0 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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) {
Expand Down
7 changes: 7 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit b881b94

Please sign in to comment.