Skip to content

Commit b881b94

Browse files
committed
Custom error handler
1 parent 24d49d4 commit b881b94

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

app.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,17 @@ var ErrNoRootCommand = errors.New("no root command provided")
1414
// App represents a command line application.
1515
type App struct {
1616
CobraProvider
17+
ErrorHandler
1718
Exit func(code int)
1819
root *cobra.Command
1920
}
2021

22+
// ErrorHandler is a function that will be used to handle the errors. The
23+
// function will be called regardless if an error has been received, so proper
24+
// error checking is required. If true is returned, the default error handling
25+
// will not be used.
26+
type ErrorHandler func(err error) bool
27+
2128
// CobraProvider is used to provide a Cobra command.
2229
type CobraProvider interface {
2330
Command() *cobra.Command
@@ -33,8 +40,13 @@ func New(cp CobraProvider) *App {
3340

3441
// ExecuteOrDie will execute the application or perform os.Exit in case of error.
3542
func (a *App) ExecuteOrDie(options ...Option) {
36-
if err := a.Execute(options...); err != nil {
37-
a.Exit(retcode.Calc(err))
43+
err := a.Execute(options...)
44+
if a.ErrorHandler == nil {
45+
a.defaultErrorHandler(err)
46+
return
47+
}
48+
if !a.ErrorHandler(err) {
49+
a.defaultErrorHandler(err)
3850
}
3951
}
4052

@@ -64,3 +76,9 @@ func (a *App) init() error {
6476
}
6577
return nil
6678
}
79+
80+
func (a *App) defaultErrorHandler(err error) {
81+
if err != nil {
82+
a.Exit(retcode.Calc(err))
83+
}
84+
}

app_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
func TestExecuteOrDie(t *testing.T) {
1515
var buf bytes.Buffer
1616
var retcode int
17+
var err error
1718
commandline.New(new(testApp)).ExecuteOrDie(
1819
commandline.WithCommand(func(cmd *cobra.Command) {
1920
cmd.SetOut(&buf)
@@ -23,9 +24,14 @@ func TestExecuteOrDie(t *testing.T) {
2324
commandline.WithExit(func(code int) {
2425
retcode = code
2526
}),
27+
commandline.WithErrorHandler(func(merr error) bool {
28+
err = merr
29+
return false
30+
}),
2631
)
2732
assert.Equal(t, `example Input: ["arg1" "arg2"]`, buf.String())
2833
assert.Equal(t, 133, retcode)
34+
assert.Assert(t, err != nil)
2935
}
3036

3137
func TestExit(t *testing.T) {

options.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ func WithCommand(fn func(cmd *cobra.Command)) Option {
4141
}
4242
}
4343

44+
// WithErrorHandler will allow changing the default error handler.
45+
func WithErrorHandler(fn ErrorHandler) Option {
46+
return func(app *App) {
47+
app.ErrorHandler = fn
48+
}
49+
}
50+
4451
// WithExit creates an option which sets the exit function.
4552
func WithExit(fn func(code int)) Option {
4653
return func(app *App) {

0 commit comments

Comments
 (0)