cli
cli copied to clipboard
Return explicit usage error
Checklist
- [X] Are you running the latest v2 release? The list of releases is here.
- [X] Did you check the manual for your release? The v2 manual is here
- [X] Did you perform a search about this feature? Here's the Github guide about searching.
What problem does this solve?
I have a CLI app that has differing arg requirements based on a particular flag. Either it will be cmd sub --all <first> or cmd sub <first> <second> [etc]... I can check for the arg length and return an error fine, but it would be nice to be able to do something like
if c.Args().Len() == 0 {
return cli.UsageErr(fmt.Errorf("requires at least one argument"))
}
all := c.Bool("all")
if !all {
if c.Args().Len() < 2 {
return cli.UsageErr(fmt.Errorf("missing name(s)"))
}
//...
} else {
//...
}
This way, certain errors will automatically print the command usage, while later errors can fail as normal.
Notes after digging somewhat: the most straightforward implementation would be changing handleExitCoder to handleErrorTypes, which could use errors.Is() and errors.As() and either retrofitting exitError to implement Unwrap() error, or ideally changing message from interface{} to error (unsure how feasible this is yet). Then it would be a matter of adding a new UsageError type, also implementing Unwrap() error, along with NewUsageError(error)error.
This way the two could be used in conjunction for errors which should either exit with a code, print usage or both.
Something like this: https://play.golang.org/p/jGF1iYuBl9z
Functional error options are also a possibility: https://play.golang.org/p/HMkLILVU3FP. This has the benefit of only a single type representing all of the things you might want to do specially with user errors, though it dispenses with the interface implementation paradigm, and is arguably slightly less flexible with regard to things like multierror, though I expect you could also provide a convenience ErrorStack type for the user to append on as well.
@flowchartsman This a a good idea. Would you like to submit a PR for this ?
Sure, but I wouldn't mind a little buy-in before I do an implementation. I think probably the most "correct" way to do it would be to use errors.As and then define different error wrappers for error behaviors like I mention above. Can I get a show of thumbs-up thumbs-down on that proposal?
@flowchartsman PR #1545 might help. Can you let me know if it is what you are looking for ? We cant change the interface{} to error but breaking some clients so we'd rather not
Wont fix in v2. Will be superseded by #1662 in v3