-
Notifications
You must be signed in to change notification settings - Fork 0
/
error.go
131 lines (103 loc) · 2.73 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package errors
import (
"errors"
"fmt"
)
// Error is an internal error with fields capabilities.
type Error struct {
cause error
msg string
fields []Field
}
// New create a new error.
func New(msg string, fields ...Field) error {
return &Error{msg: msg, fields: fields}
}
// Wrap creates a new error with given cause.
func Wrap(cause error, msg string, fields ...Field) error {
return &Error{cause: cause, msg: msg, fields: fields}
}
// Wrapf is like Wrap, but it does format.
func Wrapf(cause error, format string, args ...interface{}) error {
return Wrap(cause, fmt.Sprintf(format, args...))
}
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
// Errorf also records the stack trace at the point it was called.
func Errorf(format string, args ...interface{}) error {
return Wrap(nil, fmt.Sprintf(format, args...))
}
// ErrorfWithFields is like Errorf and also support Field.
func ErrorfWithFields(format string, args []interface{}, fields ...Field) error {
return Wrap(nil, fmt.Sprintf(format, args...), fields...)
}
// Error return error string.
func (e *Error) Error() string {
if e.cause == nil {
return e.msg
}
return e.msg + ": " + e.cause.Error()
}
// Cause return the cause if error.
func (e *Error) Cause() error { return e.cause }
// Unwrap return the cause if error.
func (e *Error) Unwrap() error { return e.cause }
// GetError check if the error is Error, create an empty Error if not.
func GetError(err error) (Err *Error) {
var custom *Error
ok := errors.As(err, &custom)
if ok {
return custom
}
return &Error{msg: err.Error(), cause: err}
}
// Cause return main error.
func Cause(err error) error {
type causer interface {
Unwrap() error
Error() string
}
for err != nil {
cause, ok := err.(causer)
if !ok {
break
}
myCause := cause.Unwrap()
if myCause == nil {
err = cause
break
}
err = myCause
}
return err
}
// Format is implement the fmt.Formatter for Error.
func (e *Error) Format(state fmt.State, verb rune) {
if len(e.fields) == 0 {
fmt.Fprint(state, e.Error())
return
}
switch verb {
case 'v':
if state.Flag('+') {
fmt.Fprintf(state, "%+v: %+v", e.Error(), e.fields)
return
}
if state.Flag('#') {
fmt.Fprintf(state, "%v: %#v", e.Error(), e.fields)
return
}
fmt.Fprintf(state, "%v: %v", e.Error(), e.fields)
case 's':
fmt.Fprintf(state, "%s: %s", e.Error(), e.fields)
case 'q':
fmt.Fprintf(state, "%q: %q", e.Error(), e.fields)
}
}
// AddFields to the passed error.
// passed error must be Error, if not, a new Error will create.
func AddFields(err error, fields ...Field) error {
customError := GetError(err)
customError.fields = append(customError.fields, fields...)
return customError
}