-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherror.go
90 lines (79 loc) · 1.98 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
package evs
import (
"errors"
"fmt"
)
const (
KindIO = "IO"
KindType = "Type"
KindUnknown = ""
KindValue = "Value"
initialSkip = 1
)
var (
// IncludeStack is used to determine whether or not a stacktrace should be captured with
// new errors. By default it is set to true.
IncludeStack = true
// InspectFull controls how [From] operates. By default, the full error stack will be inspected
// via [errors.As]. If any [evs.Error] exists within the stack, that error is extracted and returned.
// You can turn this behavior off, by setting InspectFull to false. This will then only check the
// error itself (without calling unwrap).
InspectFull = true
// compiler type enforcement
_ = error(&Error{})
)
type Kind string
// Error implements both the Error interface as well as Unwrap.
type Error struct {
Wraps error
Stack Stack
Details []string
Kind Kind
f Formatter
}
func newError(skip int) *Error {
skip++
err := &Error{
f: GetFormatterFunc(),
}
if IncludeStack {
err.Stack = GetStack(skip)
}
return err
}
func from(skip int, wraps error) *Error {
skip++
if InspectFull {
check := &Error{}
if errors.As(wraps, &check) {
return check
}
} else {
err, ok := wraps.(*Error)
if ok {
return err
}
}
err := newError(skip)
err.Wraps = wraps
return err
}
// Error implements the error interface.
func (err *Error) Error() string {
return fmt.Sprintf("%+v", err)
}
// Unwrap allows you to unwrap any internal error which makes the implementation compatible with [errors.As].
func (err *Error) Unwrap() error { return err.Wraps }
// Format implements the [fmt.Formatter] interface.
func (err *Error) Format(state fmt.State, verb rune) {
err.f.Format(err, state, verb)
}
// KindOf returns the Kind of this error. If it cannot determine the Kind (e.g. because
// maybe the provided error is not an [evs.Error]) it returns [KindUnknown].
func KindOf(err error) Kind {
e := &Error{}
if errors.As(err, &e) {
return e.Kind
}
return KindUnknown
}