-
Notifications
You must be signed in to change notification settings - Fork 1
/
sentinel_error.go
62 lines (50 loc) · 1.42 KB
/
sentinel_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
// Package serrors provides better sentinel errors support
package serrors
import "fmt"
type Comparer interface {
error
Is(err error) bool // Is checks if Comparer and provided error has same type
}
type Error interface {
Comparer
Wrap(cause error) wrapped // Wrap wraps provided error
WithStack() wrapped // Stack stores call stack and returns wrapped error
}
type eString = String
// sentinelError implements Error interface
type sentinelError struct {
*eString
args []interface{}
}
// New call on sentinel error is unexpected as error is already initialized
func (sentinelError) New(args ...interface{}) sentinelError {
panic("New() can be called only once")
}
// Error implements error interface
func (e sentinelError) Error() string {
return e.String()
}
// String implements fmt.Stringer interface
func (e sentinelError) String() string {
if len(e.args) == 0 {
return e.eString.String()
}
return fmt.Sprintf(e.eString.String(), e.args...)
}
// Is implements Comparer
// err could be only base String type, as we are comparing with const
func (e sentinelError) Is(err error) bool {
switch ee := err.(type) {
case String:
return *e.eString == ee
}
return false
}
// Wrap adds cause to the String error and return wrapped
func (e sentinelError) Wrap(cause error) wrapped {
return Wrap(e, cause)
}
// WithStack implements Comparer interface
func (e sentinelError) WithStack() wrapped {
return WrapWithStack(e, nil)
}