-
Notifications
You must be signed in to change notification settings - Fork 0
/
error.go
114 lines (93 loc) · 1.74 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 errors
import (
"errors"
"runtime"
"strings"
)
type stack []uintptr
type Error struct {
message string
err error
stack stack
attrs map[string]any
}
func (e *Error) Error() string {
var msgs []string
if e.message != "" {
msgs = append(msgs, e.message)
}
if e.err != nil {
if len(e.err.Error()) > 0 {
msgs = append(msgs, e.err.Error())
}
}
return strings.Join(msgs, ": ")
}
func (e *Error) Unwrap() error {
return e.err
}
func (e *Error) StackTrace() []uintptr {
return e.stack
}
func (e *Error) Attributes() map[string]any {
return e.attrs
}
func New(message string, annotators ...any) error {
err := &Error{
message: message,
err: nil,
stack: callers(),
attrs: nil,
}
if len(annotators) == 0 {
return err
}
return wrap(err, annotators...)
}
func Is(err, target error) bool {
return errors.Is(err, target)
}
func As(err error, target any) bool {
return errors.As(err, target)
}
func Join(errs ...error) error {
return errors.Join(errs...)
}
func Unwrap(err error) error {
return errors.Unwrap(err)
}
func Wrap(err error, annotators ...any) error {
if err == nil {
return nil
}
e := &Error{
message: "",
err: err,
stack: callers(),
attrs: nil,
}
if x, ok := err.(interface{ Attributes() map[string]any }); ok {
e.attrs = x.Attributes()
}
return wrap(e, annotators...)
}
func wrap(err *Error, annotators ...any) error {
for _, annotator := range annotators {
switch a := annotator.(type) {
case string:
WithMessage(a)(err)
case Attribute:
WithAttrs(a)(err)
case AnnotatorFunc:
a(err)
default:
// Do nothing (or should I panic?)
}
}
return err
}
func callers() stack {
var pcs [32]uintptr
n := runtime.Callers(3, pcs[:])
return pcs[0:n]
}