urfave/cli

Inconsistent error handling between App.OnUsageError and App.Before during App.Run

Open

#707 opened on Jan 30, 2018

View on GitHub
 (10 comments) (1 reaction) (0 assignees)Go (23,088 stars) (1,735 forks)batch import
area/v2help wantedkind/bugstatus/confirmed

Description

When OnUsageError is set for a cli.App instance, one has full control of what is printed to stderr when an error is encountered. That is not the case when setting Before.

Looking at how OnUsageError is handled in App.Run in app.go [c6eb2a0]:

if a.OnUsageError != nil {
	err := a.OnUsageError(context, err, false)
	a.handleExitCoder(context, err)
	return err
}

and for Before:

if a.Before != nil {
	beforeErr := a.Before(context)
	if beforeErr != nil {
		fmt.Fprintf(a.Writer, "%v\n\n", beforeErr)
		ShowAppHelp(context)
		a.handleExitCoder(context, beforeErr)
		err = beforeErr
		return err
	}
}

The issue I'm having is with the call to ShowAppHelp(..) when Before is set. Essentially the experience to the user is different when a usage error is encountered and I want to print custom output versus when I am checking for lets say flag value validity before running any subcommands. Ideally I would prefer the 2 if statements above to be identical and the default case to call ShowAppHelper(..) as is currently the case i.e. for Before:

if a.Before != nil {
	beforeErr := a.Before(context)
	if beforeErr != nil {
		a.handleExitCoder(context, beforeErr)
		err = beforeErr
		return err
	}
}

I've looked around to see if there is another way to modify this behavior but nothing obvious stands out.

Contributor guide