-
Notifications
You must be signed in to change notification settings - Fork 375
/
error.go
114 lines (90 loc) · 1.88 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
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
package errcode
import "fmt"
type WithCode interface {
error
Code() int32
}
// Code returns the code of the actual error without trying to unwrap it, or -1.
func Code(err error) int32 {
typed, ok := err.(WithCode)
if ok {
return typed.Code()
}
return -1
}
// LastCode walks the passed error and returns the code of the latest ErrCode, or -1.
func LastCode(err error) int32 {
if err == nil {
return -1
}
if cause := genericCause(err); cause != nil {
if ret := LastCode(cause); ret != -1 {
return ret
}
}
return Code(err)
}
// FirstCode walks the passed error and returns the code of the first ErrCode met, or -1.
func FirstCode(err error) int32 {
if err == nil {
return -1
}
if code := Code(err); code != -1 {
return code
}
if cause := genericCause(err); cause != nil {
return FirstCode(cause)
}
return -1
}
func genericCause(err error) error {
type causer interface{ Cause() error }
type wrapper interface{ Unwrap() error }
if causer, ok := err.(causer); ok {
return causer.Cause()
}
if wrapper, ok := err.(wrapper); ok {
return wrapper.Unwrap()
}
return nil
}
//
// Error
//
func (e ErrCode) Error() string {
name, ok := ErrCode_name[int32(e)]
if ok {
return fmt.Sprintf("%s(#%d)", name, e)
}
return fmt.Sprintf("UNKNOWN_ERRCODE(#%d)", e)
}
func (e ErrCode) Code() int32 {
return int32(e)
}
func (e ErrCode) Wrap(inner error) WithCode {
return wrappedError{
code: int32(e),
inner: inner,
}
}
//
// ConfigurableError
//
type wrappedError struct {
code int32
inner error
}
func (e wrappedError) Error() string {
return fmt.Sprintf("%s: %v", ErrCode(e.code), e.inner)
}
func (e wrappedError) Code() int32 {
return e.code
}
// Cause returns the inner error (github.com/pkg/errors)
func (e wrappedError) Cause() error {
return e.inner
}
// Unwrap returns the inner error (go1.13)
func (e wrappedError) Unwrap() error {
return e.inner
}