Repository navigation
Expand file tree
/
Copy patherrors.go
More file actions
98 lines (88 loc) · 2.5 KB
/
Copy patherrors.go
File metadata and controls
98 lines (88 loc) · 2.5 KB
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Note: the documentation / examples for error handling in the go-flags
// library is currently a combination of lacking and wrong:
// * https://github.com/jessevdk/go-flags/issues/306
// * https://github.com/jessevdk/go-flags/issues/361
// * https://github.com/jessevdk/go-flags/issues/377
//
// This package attempts to make working with CLI errors easier (and
// easier to maintain).
package flagswrap
import (
"errors"
"fmt"
"github.com/jessevdk/go-flags"
)
var (
ErrGoFlagsErrorWrapper = errors.New("couldn't wrap go-flags error")
// These are the errors we've noticed are handled nicely in the go-flags
// library:
goFlagsVerboseErrors = map[flags.ErrorType]bool{
flags.ErrHelp: true,
flags.ErrCommandRequired: true,
flags.ErrUnknownCommand: true,
flags.ErrUnknownFlag: true,
flags.ErrNoArgumentForBool: true,
flags.ErrInvalidChoice: true,
}
// These are the go-flags errors that are swallowed silently and require some
// logging / feedback to users:
goFlagsSilentErrors = map[flags.ErrorType]bool{
flags.ErrUnknown: true,
flags.ErrDuplicatedFlag: true,
// The remaining errors haven't had their verbosity levels confirmed;
// if you see double-logging happening in the CLI, just move the error
// in question from below up to the goFlagsVerboseErrors map.
flags.ErrExpectedArgument: true,
flags.ErrUnknownGroup: true,
flags.ErrMarshal: true,
flags.ErrRequired: true,
flags.ErrShortNameTooLong: true,
flags.ErrTag: true,
flags.ErrInvalidTag: true,
}
)
type Error struct {
wrapped error
convertErr error
flagErr *flags.Error
flagErrType flags.ErrorType
}
func WrapError(err error) *Error {
if err == nil {
return nil
}
cliErr := &Error{
wrapped: err,
}
flagsErr, ok := err.(*flags.Error)
if !ok {
cliErr.convertErr = ErrGoFlagsErrorWrapper
return cliErr
}
cliErr.flagErr = flagsErr
cliErr.flagErrType = flagsErr.Type
return cliErr
}
func (e *Error) IsHelp() bool {
return e.flagErrType == flags.ErrHelp
}
func (e *Error) IsSilent() bool {
exists, ok := goFlagsSilentErrors[e.flagErrType]
if e.convertErr == nil && ok && exists {
return true
}
return false
}
func (e *Error) IsVerbose() bool {
exists, ok := goFlagsVerboseErrors[e.flagErrType]
if e.convertErr == nil && ok && exists {
return true
}
return false
}
func (e *Error) Error() string {
return fmt.Sprintf("%v (%v) - %v", e.wrapped, e.convertErr, e.flagErrType)
}
func (e *Error) Unwrap() error {
return e.wrapped
}