It appears that errors.IsAny does not support multi-error.
| funcIsAny(errerror, references...error) bool { |
| iferr==nil { |
| for_, refErr:=rangereferences { |
| ifrefErr==nil { |
| returntrue |
| } |
| } |
| // The mark-based comparison below will never match anything if |
| // the error is nil, so don't bother with computing the marks in |
| // that case. This avoids the computational expense of computing |
| // the reference marks upfront. |
| returnfalse |
| } |
| |
| // First try using direct reference comparison. |
| forc:=err; c!=nil; c=errbase.UnwrapOnce(c) { |
| for_, refErr:=rangereferences { |
| ifrefErr==nil { |
| continue |
| } |
| isComparable:=reflect.TypeOf(refErr).Comparable() |
| ifisComparable&&c==refErr { |
| returntrue |
| } |
| // Compatibility with std go errors: if the error object itself |
| // implements Is(), try to use that. |
| iftryDelegateToIsMethod(c, refErr) { |
| returntrue |
| } |
| } |
| } |
| |
| // Try harder with marks. |
| // Note: there is a more effective recursive algorithm that ensures |
| // that any pair of string only gets compared once. Should this |
| // become a performance bottleneck, that algorithm can be considered |
| // instead. |
| refMarks:=make([]errorMark, 0, len(references)) |
| for_, refErr:=rangereferences { |
| ifrefErr==nil { |
| continue |
| } |
| refMarks=append(refMarks, getMark(refErr)) |
| } |
| forc:=err; c!=nil; c=errbase.UnwrapOnce(c) { |
| errMark:=getMark(c) |
| for_, refMark:=rangerefMarks { |
| ifequalMarks(errMark, refMark) { |
| returntrue |
| } |
| } |
| } |
| returnfalse |
| } |
errors.Is supports multi-error.
| funcIs(err, referenceerror) bool { |
| ifreference==nil { |
| returnerr==nil |
| } |
| |
| isComparable:=reflect.TypeOf(reference).Comparable() |
| |
| // Direct reference comparison is the fastest, and most |
| // likely to be true, so do this first. |
| forc:=err; c!=nil; c=errbase.UnwrapOnce(c) { |
| ifisComparable&&c==reference { |
| returntrue |
| } |
| // Compatibility with std go errors: if the error object itself |
| // implements Is(), try to use that. |
| iftryDelegateToIsMethod(c, reference) { |
| returntrue |
| } |
| |
| // Recursively try multi-error causes, if applicable. |
| for_, me:=rangeerrbase.UnwrapMulti(c) { |
| ifIs(me, reference) { |
| returntrue |
| } |
| } |
| } |
| |
| iferr==nil { |
| // Err is nil and reference is non-nil, so it cannot match. We |
| // want to short-circuit the loop below in this case, otherwise |
| // we're paying the expense of getMark() without need. |
| returnfalse |
| } |
| |
| // Not directly equal. Try harder, using error marks. We don't do |
| // this during the loop above as it may be more expensive. |
| // |
| // Note: there is a more effective recursive algorithm that ensures |
| // that any pair of string only gets compared once. Should the |
| // following code become a performance bottleneck, that algorithm |
| // can be considered instead. |
| refMark:=getMark(reference) |
| forc:=err; c!=nil; c=errbase.UnwrapOnce(c) { |
| ifequalMarks(getMark(c), refMark) { |
| returntrue |
| } |
| } |
| returnfalse |
| } |
Perhaps the following equivalent code can be added to IsAny.
// Recursively try multi-error causes, if applicable. for_, me:=rangeerrbase.UnwrapMulti(c) { ifIs(me, reference) { returntrue } }
It appears that errors.IsAny does not support multi-error.
errors/markers/markers.go
Lines 152 to 205 in c1cc191
errors.Is supports multi-error.
errors/markers/markers.go
Lines 44 to 92 in c1cc191
Perhaps the following equivalent code can be added to IsAny.