Docs around exit error behavior, + handling MultiError in HandleExitCoder

This commit is contained in:
Dan Buch
2016-04-27 09:54:08 -04:00
parent b2ac0616d1
commit d48e22a9dd
2 changed files with 50 additions and 20 deletions

View File

@@ -23,15 +23,19 @@ func (m MultiError) Error() string {
return strings.Join(errs, "\n")
}
// ExitCoder is the interface checked by `App` and `Command` for a custom exit
// code
type ExitCoder interface {
ExitCode() int
}
// ExitError fulfills both the builtin `error` interface and `ExitCoder`
type ExitError struct {
exitCode int
message string
}
// NewExitError makes a new *ExitError
func NewExitError(message string, exitCode int) *ExitError {
return &ExitError{
exitCode: exitCode,
@@ -39,22 +43,33 @@ func NewExitError(message string, exitCode int) *ExitError {
}
}
// Error returns the string message, fulfilling the interface required by
// `error`
func (ee *ExitError) Error() string {
return ee.message
}
func (ee *ExitError) String() string {
return fmt.Sprintf("%s exitcode=%v", ee.message, ee.exitCode)
}
// ExitCode returns the exit code, fulfilling the interface required by
// `ExitCoder`
func (ee *ExitError) ExitCode() int {
return ee.exitCode
}
// HandleExitCoder checks if the error fulfills the ExitCoder interface, and if
// so calls os.Exit with the given exit code.
// so prints the error to stderr (if it is non-empty) and calls os.Exit with the
// given exit code. If the given error is a MultiError, then this func is
// called on all members of the Errors slice.
func HandleExitCoder(err error) {
if exitErr, ok := err.(ExitCoder); ok {
if err.Error() != "" {
fmt.Fprintln(os.Stderr, err)
}
os.Exit(exitErr.ExitCode())
}
if multiErr, ok := err.(MultiError); ok {
for _, merr := range multiErr.Errors {
HandleExitCoder(merr)
}
}
}