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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
package errors
import (
_ "unsafe"
)
// Is reports whether any error in err's tree matches target.
//
// The tree consists of err itself, followed by the errors obtained by repeatedly
// calling Unwrap. When err wraps multiple errors, Is examines err followed by a
// depth-first traversal of its children.
//
// An error is considered to match a target if it is equal to that target or if
// it implements a method Is(error) bool such that Is(target) returns true.
//
// An error type might provide an Is method so it can be treated as equivalent
// to an existing error. For example, if MyError defines
//
// func (m MyError) Is(target error) bool { return target == fs.ErrExist }
//
// then Is(MyError{}, fs.ErrExist) returns true. See [syscall.Errno.Is] for
// an example in the standard library. An Is method should only shallowly
// compare err and the target and not call Unwrap on either.
//
//go:linkname Is errors.Is
func Is(err error, target error) bool
// IsV2 calls Is(err, target) for each target within targets.
func IsV2(err error, targets ...error) bool {
for _, target := range targets {
if Is(err, target) {
return true
}
}
return false
}
// As finds the first error in err's tree that matches target, and if one is found, sets
// target to that error value and returns true. Otherwise, it returns false.
//
// The tree consists of err itself, followed by the errors obtained by repeatedly
// calling Unwrap. When err wraps multiple errors, As examines err followed by a
// depth-first traversal of its children.
//
// An error matches target if the error's concrete value is assignable to the value
// pointed to by target, or if the error has a method As(interface{}) bool such that
// As(target) returns true. In the latter case, the As method is responsible for
// setting target.
//
// An error type might provide an As method so it can be treated as if it were a
// different error type.
//
// As panics if target is not a non-nil pointer to either a type that implements
// error, or to any interface type.
//
//go:linkname As errors.As
func As(err error, target any) bool
// AsV2 is functionally similar to As(), instead
// leveraging generics to handle allocation and
// returning of a concrete generic parameter type.
func AsV2[Type any](err error) Type {
var t Type
var ok bool
errs := []error{err}
for len(errs) > 0 {
// Pop next error to check.
err := errs[len(errs)-1]
errs = errs[:len(errs)-1]
// Check direct type.
t, ok = err.(Type)
if ok {
return t
}
// Look for .As() support.
as, ok := err.(interface {
As(target any) bool
})
if ok {
// Attempt .As().
if as.As(&t) {
return t
}
}
// Try unwrap errors.
switch u := err.(type) {
case interface{ Unwrap() error }:
errs = append(errs, u.Unwrap())
case interface{ Unwrap() []error }:
errs = append(errs, u.Unwrap()...)
}
}
return t
}
// Unwrap returns the result of calling the Unwrap method on err, if err's
// type contains an Unwrap method returning error.
// Otherwise, Unwrap returns nil.
//
// Unwrap only calls a method of the form "Unwrap() error".
// In particular Unwrap does not unwrap errors returned by [Join].
//
//go:linkname Unwrap errors.Unwrap
func Unwrap(err error) error
// UnwrapV2 is functionally similar to Unwrap(), except that
// it also handles the case of interface{ Unwrap() []error }.
func UnwrapV2(err error) []error {
switch u := err.(type) {
case interface{ Unwrap() error }:
if e := u.Unwrap(); err != nil {
return []error{e}
}
case interface{ Unwrap() []error }:
return u.Unwrap()
}
return nil
}
// Join returns an error that wraps the given errors.
// Any nil error values are discarded.
// Join returns nil if every value in errs is nil.
// The error formats as the concatenation of the strings obtained
// by calling the Error method of each element of errs, with a newline
// between each string.
//
// A non-nil error returned by Join implements the Unwrap() []error method.
//
//go:linkname Join errors.Join
func Join(errs ...error) error
|