cli icon indicating copy to clipboard operation
cli copied to clipboard

Return explicit usage error

Open flowchartsman opened this issue 4 years ago • 5 comments
trafficstars

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.

flowchartsman avatar Sep 29 '21 19:09 flowchartsman

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.

flowchartsman avatar Sep 29 '21 20:09 flowchartsman

Something like this: https://play.golang.org/p/jGF1iYuBl9z

flowchartsman avatar Sep 29 '21 21:09 flowchartsman

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 avatar Sep 29 '21 21:09 flowchartsman

@flowchartsman This a a good idea. Would you like to submit a PR for this ?

dearchap avatar Sep 15 '22 18:09 dearchap

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 avatar Sep 19 '22 02:09 flowchartsman

@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

dearchap avatar Oct 27 '22 12:10 dearchap

Wont fix in v2. Will be superseded by #1662 in v3

dearchap avatar May 21 '23 14:05 dearchap