-
Notifications
You must be signed in to change notification settings - Fork 92
/
error.go
77 lines (65 loc) · 1.61 KB
/
error.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package main
import (
"fmt"
"os"
)
// Exit codes are int values for the exit code that shell interpreter can interpret
const (
ExitCodeOK int = 0
ExitCodeError int = iota
)
// ErrorFormatter is the interface for format
type ErrorFormatter interface {
Format(s fmt.State, verb rune)
}
// ExitCoder is the wrapper interface for urfave/cli
type ExitCoder interface {
error
ExitCode() int
}
// ExitError is the wrapper struct for urfave/cli
type ExitError struct {
exitCode int
err error
}
// NewExitError makes a new ExitError
func NewExitError(exitCode int, err error) *ExitError {
return &ExitError{
exitCode: exitCode,
err: err,
}
}
// Error returns the string message, fulfilling the interface required by `error`
func (ee *ExitError) Error() string {
if ee.err == nil {
return ""
}
return fmt.Sprintf("%v", ee.err)
}
// ExitCode returns the exit code, fulfilling the interface required by `ExitCoder`
func (ee *ExitError) ExitCode() int {
return ee.exitCode
}
// HandleExit returns int value that shell interpreter can interpret as the exit code
// If err has error message, it will be displayed to stderr
// This function is heavily inspired by urfave/cli.HandleExitCoder
func HandleExit(err error) int {
if err == nil {
return ExitCodeOK
}
if exitErr, ok := err.(ExitCoder); ok {
if err.Error() != "" {
if _, ok := exitErr.(ErrorFormatter); ok {
fmt.Fprintf(os.Stderr, "%+v\n", err)
} else {
fmt.Fprintln(os.Stderr, err)
}
}
return exitErr.ExitCode()
}
if _, ok := err.(error); ok {
fmt.Fprintf(os.Stderr, "%v\n", err)
return ExitCodeError
}
return ExitCodeOK
}