-
Notifications
You must be signed in to change notification settings - Fork 1
/
failure.go
166 lines (123 loc) · 3.47 KB
/
failure.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package failure
import (
"fmt"
)
// New returns an error that formats as the given message.
func New(message string) error {
return Build(message).Done()
}
// Newf formats according to a format specifier and returns the string
// as a value that satisfies error.
func Newf(format string, a ...interface{}) error {
return Buildf(format, a...).Done()
}
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error (same as calling Newf).
func Errorf(format string, a ...interface{}) error {
return Newf(format, a...)
}
// Build returns an error builder for building an error that
// formats as the given message.
func Build(message string) Builder {
return &builder{n: &node{Message: message}}
}
// Buildf returns an error builder for building an error that
// formats according to a format specifier.
func Buildf(format string, a ...interface{}) Builder {
return Build(fmt.Sprintf(format, a...))
}
// Buildc returns an error builder for building an error which is
// based on copy of err.
func Buildc(err error) Builder {
if err == nil {
panic("err is nil")
}
return &builder{n: impersonate(err).copy()}
}
// Field returns the value (or error if not found) for a field of
// err given its name.
func Field(err error, name string) (interface{}, error) {
if err == nil {
return nil, newNoSuchFieldError(name)
}
return impersonate(err).field(name)
}
// FieldOrDefault returns the value for a field of err given its
// name or def if it doesn't exist.
func FieldOrDefault(err error, name string, def interface{}) interface{} {
v, e := Field(err, name)
if e != nil {
return def
}
return v
}
// TestField returns true only if a field named name with the value
// value exists in err.
func TestField(err error, name string, value interface{}) bool {
v, e := Field(err, name)
if e != nil {
return false
}
return v == value
}
// TestFieldRecursively returns true only if a field named name with the value
// value exists in err or one of its descendants.
func TestFieldRecursively(err error, name string, value interface{}) bool {
n := impersonate(err)
for n != nil {
if v, e := n.field(name); e == nil && v == value {
return true
}
n = n.Inner
}
return false
}
// Inner returns the inner error of err.
func Inner(err error) error {
n := impersonate(err)
if n.Inner == nil {
return nil
}
return n.Inner
}
// Origin returns the deepest inner error of err.
func Origin(err error) error {
return impersonate(err).origin()
}
// IsParentOf returns true only if inner is a descendant of err.
func IsParentOf(err, inner error) bool {
return impersonate(err).isParentOf(impersonate(inner))
}
// Same returns true only if err0 and err1 have the same message, same fields
// and their values and same descendants.
func Same(err0, err1 error) bool {
if err0 == nil && err1 == nil {
return true
}
if err0 == nil || err1 == nil {
return false
}
return impersonate(err0).same(impersonate(err1))
}
// Like returns true only if err0 and err1 have the same message
// or both nil.
func Like(err0, err1 error) bool {
if err0 == nil && err1 == nil {
return true
}
if err0 == nil || err1 == nil {
return false
}
return impersonate(err0).like(impersonate(err1))
}
// Message returns err's message field.
func Message(err error) string {
if err == nil {
panic("err is nil")
}
return impersonate(err).Message
}
// Depth returns the count for err and its descendants
func Depth(err error) int {
return impersonate(err).depth()
}