-
Notifications
You must be signed in to change notification settings - Fork 84
/
error.go
74 lines (66 loc) · 1.62 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
package diff
import (
"fmt"
)
var (
// ErrTypeMismatch Compared types do not match
ErrTypeMismatch = NewError("types do not match")
// ErrInvalidChangeType The specified change values are not unsupported
ErrInvalidChangeType = NewError("change type must be one of 'create' or 'delete'")
)
//our own version of an error, which can wrap others
type DiffError struct {
count int
message string
next error
}
//Unwrap implement 1.13 unwrap feature for compatibility
func (s *DiffError) Unwrap() error {
return s.next
}
//Error implements the error interface
func (s DiffError) Error() string {
cause := ""
if s.next != nil {
cause = s.next.Error()
}
return fmt.Sprintf(" %s (cause count %d)\n%s", s.message, s.count, cause)
}
//AppendCause appends a new cause error to the chain
func (s *DiffError) WithCause(err error) *DiffError {
if s != nil && err != nil {
s.count++
if s.next != nil {
if v, ok := err.(DiffError); ok {
s.next = v.WithCause(s.next)
} else if v, ok := err.(*DiffError); ok {
s.next = v.WithCause(s.next)
} else {
v = &DiffError{
message: "auto wrapped error",
next: err,
}
s.next = v.WithCause(s.next)
}
} else {
s.next = err
}
}
return s
}
//NewErrorf just give me a plain error with formatting
func NewErrorf(format string, messages ...interface{}) *DiffError {
return &DiffError{
message: fmt.Sprintf(format, messages...),
}
}
//NewError just give me a plain error
func NewError(message string, causes ...error) *DiffError {
s := &DiffError{
message: message,
}
for _, cause := range causes {
s.WithCause(cause) // nolint: errcheck
}
return s
}