Source file
src/errors/wrap.go
1
2
3
4
5 package errors
6
7 import (
8 "internal/reflectlite"
9 )
10
11
12
13
14
15
16
17 func Unwrap(err error) error {
18 u, ok := err.(interface {
19 Unwrap() error
20 })
21 if !ok {
22 return nil
23 }
24 return u.Unwrap()
25 }
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 func Is(err, target error) bool {
46 if err == nil || target == nil {
47 return err == target
48 }
49
50 isComparable := reflectlite.TypeOf(target).Comparable()
51 return is(err, target, isComparable)
52 }
53
54 func is(err, target error, targetComparable bool) bool {
55 for {
56 if targetComparable && err == target {
57 return true
58 }
59 if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
60 return true
61 }
62 switch x := err.(type) {
63 case interface{ Unwrap() error }:
64 err = x.Unwrap()
65 if err == nil {
66 return false
67 }
68 case interface{ Unwrap() []error }:
69 for _, err := range x.Unwrap() {
70 if is(err, target, targetComparable) {
71 return true
72 }
73 }
74 return false
75 default:
76 return false
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 func As(err error, target any) bool {
103 if err == nil {
104 return false
105 }
106 if target == nil {
107 panic("errors: target cannot be nil")
108 }
109 val := reflectlite.ValueOf(target)
110 typ := val.Type()
111 if typ.Kind() != reflectlite.Ptr || val.IsNil() {
112 panic("errors: target must be a non-nil pointer")
113 }
114 targetType := typ.Elem()
115 if targetType.Kind() != reflectlite.Interface && !targetType.Implements(errorType) {
116 panic("errors: *target must be interface or implement error")
117 }
118 return as(err, target, val, targetType)
119 }
120
121 func as(err error, target any, targetVal reflectlite.Value, targetType reflectlite.Type) bool {
122 for {
123 if reflectlite.TypeOf(err).AssignableTo(targetType) {
124 targetVal.Elem().Set(reflectlite.ValueOf(err))
125 return true
126 }
127 if x, ok := err.(interface{ As(any) bool }); ok && x.As(target) {
128 return true
129 }
130 switch x := err.(type) {
131 case interface{ Unwrap() error }:
132 err = x.Unwrap()
133 if err == nil {
134 return false
135 }
136 case interface{ Unwrap() []error }:
137 for _, err := range x.Unwrap() {
138 if err == nil {
139 continue
140 }
141 if as(err, target, targetVal, targetType) {
142 return true
143 }
144 }
145 return false
146 default:
147 return false
148 }
149 }
150 }
151
152 var errorType = reflectlite.TypeOf((*error)(nil)).Elem()
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 func AsType[E error](err error) (E, bool) {
168 if err == nil {
169 var zero E
170 return zero, false
171 }
172 var pe *E
173 return asType(err, &pe)
174 }
175
176 func asType[E error](err error, ppe **E) (_ E, _ bool) {
177 for {
178 if e, ok := err.(E); ok {
179 return e, true
180 }
181 if x, ok := err.(interface{ As(any) bool }); ok {
182 if *ppe == nil {
183 *ppe = new(E)
184 }
185 if x.As(*ppe) {
186 return **ppe, true
187 }
188 }
189 switch x := err.(type) {
190 case interface{ Unwrap() error }:
191 err = x.Unwrap()
192 if err == nil {
193 return
194 }
195 case interface{ Unwrap() []error }:
196 for _, err := range x.Unwrap() {
197 if err == nil {
198 continue
199 }
200 if x, ok := asType(err, ppe); ok {
201 return x, true
202 }
203 }
204 return
205 default:
206 return
207 }
208 }
209 }
210
View as plain text