-
Notifications
You must be signed in to change notification settings - Fork 1
/
def.go
210 lines (198 loc) · 6.4 KB
/
def.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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
package errors
// Error object
type Error interface {
// Buildable _
Buildable
// Data returns the wrapped common user data by Buildable.WithData.
// The error objects with passed Buildable.WithData will be moved
// into inner errors set, so its are excluded from Data().
Data() []interface{}
// TaggedData returns the wrapped tagged user data by
// Buildable.WithTaggedData.
TaggedData() TaggedData
// Cause returns the underlying cause of the error, if possible.
// An error value has a cause if it implements the following
// interface:
//
// type causer interface {
// Cause() error
// }
//
// If an error object does not implement Cause interface, the
// original error object will be returned.
// If the error is nil, nil will be returned without further
// investigation.
Cause() error
// Causes simply returns the wrapped inner errors.
// It doesn't consider an wrapped Code entity is an inner error too.
// So if you wanna to extract any inner error objects, use
// errors.Unwrap for instead. The errors.Unwrap could extract all
// of them one by one:
//
// var err = errors.New("hello").WithErrors(io.EOF, io.ShortBuffers)
// var e error = err
// for e != nil {
// e = errors.Unwrap(err)
// }
//
Causes() []error
}
// Buildable provides a fluent calling interface to make error building easy.
// Buildable is an error interface too.
type Buildable interface {
// error interface
error
// WithSkip specifies a special number of stack frames that will be ignored.
WithSkip(skip int) Buildable
// WithMessage formats the error message
WithMessage(message string, args ...interface{}) Buildable
// WithCode specifies an error code.
// An error code `Code` is a integer number with error interface
// supported.
WithCode(code Code) Buildable
// WithErrors attaches the given errs as inner errors.
// WithErrors is like our old Attach().
//
// It wraps the inner errors into underlying container and
// represents them all in a singular up-level error object.
// The wrapped inner errors can be retrieved with errors.Causes:
//
// var err = errors.New("hello").WithErrors(io.EOF, io.ShortBuffers)
// var errs []error = errors.Causes(err)
//
// Or, use As() to extract its:
//
// var errs []error
// errors.As(err, &errs)
//
// Or, use Unwrap() for its:
//
// var e error = err
// for e != nil {
// e = errors.Unwrap(err)
// }
//
// WithErrors attach child errors into an error container.
// For a container which has IsEmpty() interface, it would not be
// attached if it is empty (i.e. no errors).
// For a nil error object, it will be ignored.
WithErrors(errs ...error) Buildable
// WithData appends errs if the general object is a error object.
//
// StackTrace of errs will be copied to callee so that you can get a
// trace output nearer by the last error.
//
// defer-recover block typically is a better place of WithData(). For example:
//
// defer func() {
// if e := recover(); e != nil {
// err = errors.New("[recovered] copyTo unsatisfied ([%v] %v -> [%v] %v), causes: %v",
// c.indirectType(from.Type()), from, c.indirectType(to.Type()), to, e).
// WithData(e) // StackTrace of e -> err
// n := log.CalcStackFrames(1) // skip defer-recover frame at first
// log.Skip(n).Errorf("%v", err) // skip go-lib frames and defer-recover frame, back to the point throwing panic
// }
// }()
//
WithData(errs ...interface{}) Buildable
// WithTaggedData appends user data with tag into internal container.
// These data can be retrieved by
WithTaggedData(siteScenes TaggedData) Buildable
// WithCause sets the underlying error manually if necessary.
WithCause(cause error) Buildable
// End could terminate the with-build stream calls without any return value.
End()
// Container _
Container
// FormatWith create a new error based on an exists error template
// with the given live args, the new error instance will be formatted.
//
// While you New an Error with format template without supplying
// the args at same time, you'll create an error message template.
// You could feed the live args later.
// A sample is:
//
// errTmpl := errors.New("template here: %v")
// // ...
// err = errTmpl.FormatWith("good day")
// println(err) // got: template here: good day
// err = errTmpl.FormatWith("bye")
// println(err) // got: template here: bye
//
FormatWith(args ...interface{}) error
}
type causer interface {
// Cause returns the underlying cause of the error, if possible.
// An error value has a cause if it implements the following
// interface:
//
// type causer interface {
// Cause() error
// }
//
// If an error object does not implement Cause interface, the
// original error object will be returned.
// If the error is nil, nil will be returned without further
// investigation.
Cause() error
}
// causers is a tool interface. In your scene, use errors.Causes(err)
// to extract the inner errors. Or, use As():
//
// err := New("many inner errors").WithErrors(e1,e2,e3)
// var errs []error
// errors.As(err, &errs)
// errs = errors.Causes(err)
//
// You may extract the inner errors one by one:
//
// var e error = err
// for e != nil {
// e = errors.Unwrap(err)
// }
//
type causers interface {
// Causes _
Causes() []error
}
// Container represents an error container which can hold a group
// of inner errors.
type Container interface {
// IsEmpty tests has attached errors
IsEmpty() bool
// Defer can be used as a defer function to simplify your codes.
//
// The codes:
//
// func some(){
// // as a inner errors container
// child := func() (err error) {
// errContainer := errors.New("")
// defer errContainer.Defer(&err)
//
// for _, r := range []error{io.EOF, io.ErrClosedPipe, errors.Internal} {
// errContainer.Attach(r)
// }
//
// return
// }
//
// err := child()
// t.Logf("failed: %+v", err)
// }
//
Defer(err *error)
// Attachable _
Attachable
}
// Attachable _
type Attachable interface {
// Attach collects the errors except it's nil
//
// StackTrace of errs will be copied to callee so that you can get a
// trace output nearer by the last error.
//
Attach(errs ...error)
}
// TaggedData _
type TaggedData map[string]interface{}