diff options
Diffstat (limited to 'vendor/github.com/hashicorp/errwrap/errwrap.go')
-rw-r--r-- | vendor/github.com/hashicorp/errwrap/errwrap.go | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/errwrap/errwrap.go b/vendor/github.com/hashicorp/errwrap/errwrap.go new file mode 100644 index 0000000..a733bef --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/errwrap.go | |||
@@ -0,0 +1,169 @@ | |||
1 | // Package errwrap implements methods to formalize error wrapping in Go. | ||
2 | // | ||
3 | // All of the top-level functions that take an `error` are built to be able | ||
4 | // to take any error, not just wrapped errors. This allows you to use errwrap | ||
5 | // without having to type-check and type-cast everywhere. | ||
6 | package errwrap | ||
7 | |||
8 | import ( | ||
9 | "errors" | ||
10 | "reflect" | ||
11 | "strings" | ||
12 | ) | ||
13 | |||
14 | // WalkFunc is the callback called for Walk. | ||
15 | type WalkFunc func(error) | ||
16 | |||
17 | // Wrapper is an interface that can be implemented by custom types to | ||
18 | // have all the Contains, Get, etc. functions in errwrap work. | ||
19 | // | ||
20 | // When Walk reaches a Wrapper, it will call the callback for every | ||
21 | // wrapped error in addition to the wrapper itself. Since all the top-level | ||
22 | // functions in errwrap use Walk, this means that all those functions work | ||
23 | // with your custom type. | ||
24 | type Wrapper interface { | ||
25 | WrappedErrors() []error | ||
26 | } | ||
27 | |||
28 | // Wrap defines that outer wraps inner, returning an error type that | ||
29 | // can be cleanly used with the other methods in this package, such as | ||
30 | // Contains, GetAll, etc. | ||
31 | // | ||
32 | // This function won't modify the error message at all (the outer message | ||
33 | // will be used). | ||
34 | func Wrap(outer, inner error) error { | ||
35 | return &wrappedError{ | ||
36 | Outer: outer, | ||
37 | Inner: inner, | ||
38 | } | ||
39 | } | ||
40 | |||
41 | // Wrapf wraps an error with a formatting message. This is similar to using | ||
42 | // `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap | ||
43 | // errors, you should replace it with this. | ||
44 | // | ||
45 | // format is the format of the error message. The string '{{err}}' will | ||
46 | // be replaced with the original error message. | ||
47 | func Wrapf(format string, err error) error { | ||
48 | outerMsg := "<nil>" | ||
49 | if err != nil { | ||
50 | outerMsg = err.Error() | ||
51 | } | ||
52 | |||
53 | outer := errors.New(strings.Replace( | ||
54 | format, "{{err}}", outerMsg, -1)) | ||
55 | |||
56 | return Wrap(outer, err) | ||
57 | } | ||
58 | |||
59 | // Contains checks if the given error contains an error with the | ||
60 | // message msg. If err is not a wrapped error, this will always return | ||
61 | // false unless the error itself happens to match this msg. | ||
62 | func Contains(err error, msg string) bool { | ||
63 | return len(GetAll(err, msg)) > 0 | ||
64 | } | ||
65 | |||
66 | // ContainsType checks if the given error contains an error with | ||
67 | // the same concrete type as v. If err is not a wrapped error, this will | ||
68 | // check the err itself. | ||
69 | func ContainsType(err error, v interface{}) bool { | ||
70 | return len(GetAllType(err, v)) > 0 | ||
71 | } | ||
72 | |||
73 | // Get is the same as GetAll but returns the deepest matching error. | ||
74 | func Get(err error, msg string) error { | ||
75 | es := GetAll(err, msg) | ||
76 | if len(es) > 0 { | ||
77 | return es[len(es)-1] | ||
78 | } | ||
79 | |||
80 | return nil | ||
81 | } | ||
82 | |||
83 | // GetType is the same as GetAllType but returns the deepest matching error. | ||
84 | func GetType(err error, v interface{}) error { | ||
85 | es := GetAllType(err, v) | ||
86 | if len(es) > 0 { | ||
87 | return es[len(es)-1] | ||
88 | } | ||
89 | |||
90 | return nil | ||
91 | } | ||
92 | |||
93 | // GetAll gets all the errors that might be wrapped in err with the | ||
94 | // given message. The order of the errors is such that the outermost | ||
95 | // matching error (the most recent wrap) is index zero, and so on. | ||
96 | func GetAll(err error, msg string) []error { | ||
97 | var result []error | ||
98 | |||
99 | Walk(err, func(err error) { | ||
100 | if err.Error() == msg { | ||
101 | result = append(result, err) | ||
102 | } | ||
103 | }) | ||
104 | |||
105 | return result | ||
106 | } | ||
107 | |||
108 | // GetAllType gets all the errors that are the same type as v. | ||
109 | // | ||
110 | // The order of the return value is the same as described in GetAll. | ||
111 | func GetAllType(err error, v interface{}) []error { | ||
112 | var result []error | ||
113 | |||
114 | var search string | ||
115 | if v != nil { | ||
116 | search = reflect.TypeOf(v).String() | ||
117 | } | ||
118 | Walk(err, func(err error) { | ||
119 | var needle string | ||
120 | if err != nil { | ||
121 | needle = reflect.TypeOf(err).String() | ||
122 | } | ||
123 | |||
124 | if needle == search { | ||
125 | result = append(result, err) | ||
126 | } | ||
127 | }) | ||
128 | |||
129 | return result | ||
130 | } | ||
131 | |||
132 | // Walk walks all the wrapped errors in err and calls the callback. If | ||
133 | // err isn't a wrapped error, this will be called once for err. If err | ||
134 | // is a wrapped error, the callback will be called for both the wrapper | ||
135 | // that implements error as well as the wrapped error itself. | ||
136 | func Walk(err error, cb WalkFunc) { | ||
137 | if err == nil { | ||
138 | return | ||
139 | } | ||
140 | |||
141 | switch e := err.(type) { | ||
142 | case *wrappedError: | ||
143 | cb(e.Outer) | ||
144 | Walk(e.Inner, cb) | ||
145 | case Wrapper: | ||
146 | cb(err) | ||
147 | |||
148 | for _, err := range e.WrappedErrors() { | ||
149 | Walk(err, cb) | ||
150 | } | ||
151 | default: | ||
152 | cb(err) | ||
153 | } | ||
154 | } | ||
155 | |||
156 | // wrappedError is an implementation of error that has both the | ||
157 | // outer and inner errors. | ||
158 | type wrappedError struct { | ||
159 | Outer error | ||
160 | Inner error | ||
161 | } | ||
162 | |||
163 | func (w *wrappedError) Error() string { | ||
164 | return w.Outer.Error() | ||
165 | } | ||
166 | |||
167 | func (w *wrappedError) WrappedErrors() []error { | ||
168 | return []error{w.Outer, w.Inner} | ||
169 | } | ||