Merge pull request #628 from phinnaeus/master
Allow custom ExitError handler function
This commit is contained in:
commit
7bc6a0acff
26
app.go
26
app.go
@ -83,6 +83,9 @@ type App struct {
|
|||||||
Writer io.Writer
|
Writer io.Writer
|
||||||
// ErrWriter writes error output
|
// ErrWriter writes error output
|
||||||
ErrWriter io.Writer
|
ErrWriter io.Writer
|
||||||
|
// Execute this function to handle ExitErrors. If not provided, HandleExitCoder is provided to
|
||||||
|
// function as a default, so this is optional.
|
||||||
|
ExitErrHandler ExitErrHandlerFunc
|
||||||
// Other custom info
|
// Other custom info
|
||||||
Metadata map[string]interface{}
|
Metadata map[string]interface{}
|
||||||
// Carries a function which returns app specific info.
|
// Carries a function which returns app specific info.
|
||||||
@ -207,7 +210,7 @@ func (a *App) Run(arguments []string) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if a.OnUsageError != nil {
|
if a.OnUsageError != nil {
|
||||||
err := a.OnUsageError(context, err, false)
|
err := a.OnUsageError(context, err, false)
|
||||||
HandleExitCoder(err)
|
a.handleExitCoder(context, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
|
fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
|
||||||
@ -240,8 +243,9 @@ func (a *App) Run(arguments []string) (err error) {
|
|||||||
if a.Before != nil {
|
if a.Before != nil {
|
||||||
beforeErr := a.Before(context)
|
beforeErr := a.Before(context)
|
||||||
if beforeErr != nil {
|
if beforeErr != nil {
|
||||||
|
fmt.Fprintf(a.Writer, "%v\n\n", beforeErr)
|
||||||
ShowAppHelp(context)
|
ShowAppHelp(context)
|
||||||
HandleExitCoder(beforeErr)
|
a.handleExitCoder(context, beforeErr)
|
||||||
err = beforeErr
|
err = beforeErr
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -263,7 +267,7 @@ func (a *App) Run(arguments []string) (err error) {
|
|||||||
// Run default Action
|
// Run default Action
|
||||||
err = HandleAction(a.Action, context)
|
err = HandleAction(a.Action, context)
|
||||||
|
|
||||||
HandleExitCoder(err)
|
a.handleExitCoder(context, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +334,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if a.OnUsageError != nil {
|
if a.OnUsageError != nil {
|
||||||
err = a.OnUsageError(context, err, true)
|
err = a.OnUsageError(context, err, true)
|
||||||
HandleExitCoder(err)
|
a.handleExitCoder(context, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
|
fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
|
||||||
@ -352,7 +356,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
afterErr := a.After(context)
|
afterErr := a.After(context)
|
||||||
if afterErr != nil {
|
if afterErr != nil {
|
||||||
HandleExitCoder(err)
|
a.handleExitCoder(context, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = NewMultiError(err, afterErr)
|
err = NewMultiError(err, afterErr)
|
||||||
} else {
|
} else {
|
||||||
@ -365,7 +369,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
|||||||
if a.Before != nil {
|
if a.Before != nil {
|
||||||
beforeErr := a.Before(context)
|
beforeErr := a.Before(context)
|
||||||
if beforeErr != nil {
|
if beforeErr != nil {
|
||||||
HandleExitCoder(beforeErr)
|
a.handleExitCoder(context, beforeErr)
|
||||||
err = beforeErr
|
err = beforeErr
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -383,7 +387,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
|||||||
// Run default Action
|
// Run default Action
|
||||||
err = HandleAction(a.Action, context)
|
err = HandleAction(a.Action, context)
|
||||||
|
|
||||||
HandleExitCoder(err)
|
a.handleExitCoder(context, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,6 +468,14 @@ func (a *App) appendFlag(flag Flag) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) handleExitCoder(context *Context, err error) {
|
||||||
|
if a.ExitErrHandler != nil {
|
||||||
|
a.ExitErrHandler(context, err)
|
||||||
|
} else {
|
||||||
|
HandleExitCoder(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Author represents someone who has contributed to a cli project.
|
// Author represents someone who has contributed to a cli project.
|
||||||
type Author struct {
|
type Author struct {
|
||||||
Name string // The Authors name
|
Name string // The Authors name
|
||||||
|
36
app_test.go
36
app_test.go
@ -1658,6 +1658,42 @@ func TestHandleAction_WithInvalidFuncReturnSignature(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHandleExitCoder_Default(t *testing.T) {
|
||||||
|
app := NewApp()
|
||||||
|
fs, err := flagSet(app.Name, app.Flags)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error creating FlagSet: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := NewContext(app, fs, nil)
|
||||||
|
app.handleExitCoder(ctx, NewExitError("Default Behavior Error", 42))
|
||||||
|
|
||||||
|
output := fakeErrWriter.String()
|
||||||
|
if !strings.Contains(output, "Default") {
|
||||||
|
t.Fatalf("Expected Default Behavior from Error Handler but got: %s", output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleExitCoder_Custom(t *testing.T) {
|
||||||
|
app := NewApp()
|
||||||
|
fs, err := flagSet(app.Name, app.Flags)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error creating FlagSet: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
app.ExitErrHandler = func(_ *Context, _ error) {
|
||||||
|
fmt.Fprintln(ErrWriter, "I'm a Custom error handler, I print what I want!")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := NewContext(app, fs, nil)
|
||||||
|
app.handleExitCoder(ctx, NewExitError("Default Behavior Error", 42))
|
||||||
|
|
||||||
|
output := fakeErrWriter.String()
|
||||||
|
if !strings.Contains(output, "Custom") {
|
||||||
|
t.Fatalf("Expected Custom Behavior from Error Handler but got: %s", output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestHandleAction_WithUnknownPanic(t *testing.T) {
|
func TestHandleAction_WithUnknownPanic(t *testing.T) {
|
||||||
defer func() { refute(t, recover(), nil) }()
|
defer func() { refute(t, recover(), nil) }()
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ func (c Command) Run(ctx *Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if c.OnUsageError != nil {
|
if c.OnUsageError != nil {
|
||||||
err := c.OnUsageError(context, err, false)
|
err := c.OnUsageError(context, err, false)
|
||||||
HandleExitCoder(err)
|
context.App.handleExitCoder(context, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error())
|
fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error())
|
||||||
@ -184,7 +184,7 @@ func (c Command) Run(ctx *Context) (err error) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
afterErr := c.After(context)
|
afterErr := c.After(context)
|
||||||
if afterErr != nil {
|
if afterErr != nil {
|
||||||
HandleExitCoder(err)
|
context.App.handleExitCoder(context, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = NewMultiError(err, afterErr)
|
err = NewMultiError(err, afterErr)
|
||||||
} else {
|
} else {
|
||||||
@ -198,7 +198,7 @@ func (c Command) Run(ctx *Context) (err error) {
|
|||||||
err = c.Before(context)
|
err = c.Before(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ShowCommandHelp(context, c.Name)
|
ShowCommandHelp(context, c.Name)
|
||||||
HandleExitCoder(err)
|
context.App.handleExitCoder(context, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +210,7 @@ func (c Command) Run(ctx *Context) (err error) {
|
|||||||
err = HandleAction(c.Action, context)
|
err = HandleAction(c.Action, context)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleExitCoder(err)
|
context.App.handleExitCoder(context, err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
5
funcs.go
5
funcs.go
@ -23,6 +23,10 @@ type CommandNotFoundFunc func(*Context, string)
|
|||||||
// is displayed and the execution is interrupted.
|
// is displayed and the execution is interrupted.
|
||||||
type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error
|
type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error
|
||||||
|
|
||||||
|
// ExitErrHandlerFunc is executed if provided in order to handle ExitError values
|
||||||
|
// returned by Actions and Before/After functions.
|
||||||
|
type ExitErrHandlerFunc func(context *Context, err error)
|
||||||
|
|
||||||
// FlagStringFunc is used by the help generation to display a flag, which is
|
// FlagStringFunc is used by the help generation to display a flag, which is
|
||||||
// expected to be a single line.
|
// expected to be a single line.
|
||||||
type FlagStringFunc func(Flag) string
|
type FlagStringFunc func(Flag) string
|
||||||
@ -34,3 +38,4 @@ type FlagNamePrefixFunc func(fullName, placeholder string) string
|
|||||||
// FlagEnvHintFunc is used by the default FlagStringFunc to annotate flag help
|
// FlagEnvHintFunc is used by the default FlagStringFunc to annotate flag help
|
||||||
// with the environment variable details.
|
// with the environment variable details.
|
||||||
type FlagEnvHintFunc func(envVar, str string) string
|
type FlagEnvHintFunc func(envVar, str string) string
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user