...
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 func Unwrap(err error) error {
15 u, ok := err.(interface {
16 Unwrap() error
17 })
18 if !ok {
19 return nil
20 }
21 return u.Unwrap()
22 }
23
24
25
26
27
28
29
30
31 func Is(err, target error) bool {
32 if target == nil {
33 return err == target
34 }
35
36 isComparable := reflectlite.TypeOf(target).Comparable()
37 for {
38 if isComparable && err == target {
39 return true
40 }
41 if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
42 return true
43 }
44
45
46
47 if err = Unwrap(err); err == nil {
48 return false
49 }
50 }
51 }
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 func As(err error, target interface{}) bool {
67 if target == nil {
68 panic("errors: target cannot be nil")
69 }
70 val := reflectlite.ValueOf(target)
71 typ := val.Type()
72 if typ.Kind() != reflectlite.Ptr || val.IsNil() {
73 panic("errors: target must be a non-nil pointer")
74 }
75 if e := typ.Elem(); e.Kind() != reflectlite.Interface && !e.Implements(errorType) {
76 panic("errors: *target must be interface or implement error")
77 }
78 targetType := typ.Elem()
79 for err != nil {
80 if reflectlite.TypeOf(err).AssignableTo(targetType) {
81 val.Elem().Set(reflectlite.ValueOf(err))
82 return true
83 }
84 if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) {
85 return true
86 }
87 err = Unwrap(err)
88 }
89 return false
90 }
91
92 var errorType = reflectlite.TypeOf((*error)(nil)).Elem()
93
View as plain text