...
1
2
3
4 package errors
5
6 import (
7 "reflect"
8 )
9
10 type unwrapper interface {
11 Unwrap() error
12 }
13
14
15
16
17 func As(err error, target interface{}) bool {
18 targetType := reflect.TypeOf(target)
19
20 for {
21 errType := reflect.TypeOf(err)
22
23 if errType == nil {
24 return false
25 }
26
27 if reflect.PtrTo(errType) == targetType {
28 reflect.ValueOf(target).Elem().Set(reflect.ValueOf(err))
29 return true
30 }
31
32 wrapped, ok := err.(unwrapper)
33 if ok {
34 err = wrapped.Unwrap()
35 } else {
36 return false
37 }
38 }
39 }
40
41
42
43
44 func Is(e error, original error) bool {
45 if e == original {
46 return true
47 }
48
49 if e, ok := e.(*Error); ok {
50 return Is(e.Err, original)
51 }
52
53 if original, ok := original.(*Error); ok {
54 return Is(e, original.Err)
55 }
56
57 return false
58 }
59
60
61
62
63
64
65
66
67
68
69
70
71 func Join(errs ...error) error {
72 n := 0
73 for _, err := range errs {
74 if err != nil {
75 n++
76 }
77 }
78 if n == 0 {
79 return nil
80 }
81 e := &joinError{
82 errs: make([]error, 0, n),
83 }
84 for _, err := range errs {
85 if err != nil {
86 e.errs = append(e.errs, err)
87 }
88 }
89 return e
90 }
91
92 type joinError struct {
93 errs []error
94 }
95
96 func (e *joinError) Error() string {
97 var b []byte
98 for i, err := range e.errs {
99 if i > 0 {
100 b = append(b, '\n')
101 }
102 b = append(b, err.Error()...)
103 }
104 return string(b)
105 }
106
107 func (e *joinError) Unwrap() []error {
108 return e.errs
109 }
110
111
112
113
114
115
116
117 func Unwrap(err error) error {
118 u, ok := err.(interface {
119 Unwrap() error
120 })
121 if !ok {
122 return nil
123 }
124 return u.Unwrap()
125 }
126
View as plain text