1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 package errors
6 7 // No imports needed — reflectlite removed.
8 9 // Unwrap returns the result of calling the Unwrap method on err, if err's
10 // type contains an Unwrap method returning error.
11 // Otherwise, Unwrap returns nil.
12 //
13 // Unwrap only calls a method of the form "Unwrap() error".
14 // In particular Unwrap does not unwrap errors returned by [Join].
15 func Unwrap(err error) error {
16 u, ok := err.(interface {
17 Unwrap() error
18 })
19 if !ok {
20 return nil
21 }
22 return u.Unwrap()
23 }
24 25 // Is reports whether any error in err's tree matches target.
26 //
27 // The tree consists of err itself, followed by the errors obtained by repeatedly
28 // calling its Unwrap() error or Unwrap() []error method. When err wraps multiple
29 // errors, Is examines err followed by a depth-first traversal of its children.
30 //
31 // An error is considered to match a target if it is equal to that target or if
32 // it implements a method Is(error) bool such that Is(target) returns true.
33 //
34 // An error type might provide an Is method so it can be treated as equivalent
35 // to an existing error. For example, if MyError defines
36 //
37 // func (m MyError) Is(target error) bool { return target == fs.ErrExist }
38 //
39 // then Is(MyError{}, fs.ErrExist) returns true. See [syscall.Errno.Is] for
40 // an example in the standard library. An Is method should only shallowly
41 // compare err and the target and not call [Unwrap] on either.
42 func Is(err, target error) bool {
43 if err == nil || target == nil {
44 return err == target
45 }
46 47 return is(err, target, true)
48 }
49 50 func is(err, target error, targetComparable bool) bool {
51 for {
52 if targetComparable && err == target {
53 return true
54 }
55 if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
56 return true
57 }
58 switch x := err.(type) {
59 case interface{ Unwrap() error }:
60 err = x.Unwrap()
61 if err == nil {
62 return false
63 }
64 case interface{ Unwrap() []error }:
65 for _, err := range x.Unwrap() {
66 if is(err, target, targetComparable) {
67 return true
68 }
69 }
70 return false
71 default:
72 return false
73 }
74 }
75 }
76 77 // As was removed — it requires reflect for runtime type matching.
78 // Use type assertions or errors.Is instead.
79