2022-05-08 17:49:45 +00:00
|
|
|
package errors
|
|
|
|
|
|
|
|
import (
|
2024-06-21 18:36:58 +00:00
|
|
|
"errors"
|
2022-05-08 17:49:45 +00:00
|
|
|
)
|
|
|
|
|
2024-06-21 18:36:58 +00:00
|
|
|
// See: errors.Is().
|
|
|
|
func Is(err error, target error) bool { return errors.Is(err, target) }
|
2023-11-30 16:22:34 +00:00
|
|
|
|
|
|
|
// 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
|
2023-04-29 16:44:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2024-06-21 18:36:58 +00:00
|
|
|
// See: errors.As().
|
|
|
|
func As(err error, target any) bool { return errors.As(err, target) }
|
2022-05-08 17:49:45 +00:00
|
|
|
|
2023-11-30 16:22:34 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2024-06-21 18:36:58 +00:00
|
|
|
// See: errors.Unwrap().
|
|
|
|
func Unwrap(err error) error { return errors.Unwrap(err) }
|
2023-11-30 16:22:34 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2024-06-21 18:36:58 +00:00
|
|
|
// See: errors.Join().
|
|
|
|
func Join(errs ...error) error { return errors.Join(errs...) }
|