Skip to content

Subcommands should have first-class support for errors #8

@Carrotman42

Description

@Carrotman42

Currently, the CommandRun.Run method returns an int. I suspect this is because the original design wanted commands to decide their exit code, but it causes some unfortunate boilerplate: most commands will end up with an error value, and have to manually print it out and decide some code to return, adding a few lines on every return statement.

Some people mitigate some awkwardness by introducing a helper function to call, which translates an error into an int (and prints non-nil errors), but that has other awkwardness in that you have to remember to use that in every return statement in every command's top-level Run method.

Instead of a helper function that you have to call, I recently introduced a wrapper type in my project which allows commands to implement a Run method which returns an error, and then does the error check and translation to integer code in one place. (It also fixes the lack of context.) It works for my project, but ideally this convenience would be pushed into this library too for everyone to share.

I would suggest instead to have the Run method return an error instead of an int; I suspect most commands would be content with exiting with 0 on a nil error, and a 1 on an arbitrary error. For those (few) commands which want to control their exit code, we can introduce an extra type like:

type ExitCode struct {
   Err error
   Code int
}

Directly changing the CommandRun function would be a breaking change, and I'm not sure how amenable people are to that. (With Go modules, it should be slightly easier to avoid breaking people? I think...) But an obvious second choice would be to deprecate the old type and make a new one which returns an error (and, ideally, takes a context too to solve #4).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions