From 6353df8bca63075a24ee736ba36055f4e87e334a Mon Sep 17 00:00:00 2001 From: Alejandro Lopez Date: Fri, 4 Aug 2023 11:43:36 +0300 Subject: [PATCH] [#142] Fix unwrapErr for go 1.20 Signed-off-by: Alejandro Lopez --- client/errors.go | 65 ++++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/client/errors.go b/client/errors.go index 769b442..64144b6 100644 --- a/client/errors.go +++ b/client/errors.go @@ -1,85 +1,64 @@ package client import ( - "errors" "fmt" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" ) -// unwraps err using errors.Unwrap and returns the result. -func unwrapErr(err error) error { - for e := errors.Unwrap(err); e != nil; e = errors.Unwrap(err) { - err = e +// wrapsErrType returns true if any error in the error tree of err is of type E. +func wrapsErrType[E error](err error) bool { + switch e := err.(type) { + case E: + return true + case interface{ Unwrap() error }: + return wrapsErrType[E](e.Unwrap()) + case interface{ Unwrap() []error }: + for _, ei := range e.Unwrap() { + if wrapsErrType[E](ei) { + return true + } + } + return false + default: + return false } - - return err } // IsErrContainerNotFound checks if err corresponds to FrostFS status // return corresponding to missing container. Supports wrapped errors. func IsErrContainerNotFound(err error) bool { - switch unwrapErr(err).(type) { - default: - return false - case *apistatus.ContainerNotFound: - return true - } + return wrapsErrType[*apistatus.ContainerNotFound](err) } // IsErrEACLNotFound checks if err corresponds to FrostFS status // return corresponding to missing eACL table. Supports wrapped errors. func IsErrEACLNotFound(err error) bool { - switch unwrapErr(err).(type) { - default: - return false - case *apistatus.EACLNotFound: - return true - } + return wrapsErrType[*apistatus.EACLNotFound](err) } // IsErrObjectNotFound checks if err corresponds to FrostFS status // return corresponding to missing object. Supports wrapped errors. func IsErrObjectNotFound(err error) bool { - switch unwrapErr(err).(type) { - default: - return false - case *apistatus.ObjectNotFound: - return true - } + return wrapsErrType[*apistatus.ObjectNotFound](err) } // IsErrObjectAlreadyRemoved checks if err corresponds to FrostFS status // return corresponding to already removed object. Supports wrapped errors. func IsErrObjectAlreadyRemoved(err error) bool { - switch unwrapErr(err).(type) { - default: - return false - case *apistatus.ObjectAlreadyRemoved: - return true - } + return wrapsErrType[*apistatus.ObjectAlreadyRemoved](err) } // IsErrSessionExpired checks if err corresponds to FrostFS status return // corresponding to expired session. Supports wrapped errors. func IsErrSessionExpired(err error) bool { - switch unwrapErr(err).(type) { - default: - return false - case *apistatus.SessionTokenExpired: - return true - } + return wrapsErrType[*apistatus.SessionTokenExpired](err) } // IsErrSessionNotFound checks if err corresponds to FrostFS status return // corresponding to missing session. Supports wrapped errors. func IsErrSessionNotFound(err error) bool { - switch unwrapErr(err).(type) { - default: - return false - case *apistatus.SessionTokenNotFound: - return true - } + return wrapsErrType[*apistatus.SessionTokenNotFound](err) } // returns error describing missing field with the given name.