[#278] client: Support wrapped errors in error checkers
Client errors are quite often wrapped in context. When checking a specific error, it is required not to lose the ability to determine it, regardless of the attached context. In previous implementation `IsErr*` functions didn't support wrapped errors. Make `IsErr*` functions to preliminarily unwrap `error` argument before type assertion. Use `errors.Unwrap` for this instead of `errors.As` since the latter has the overhead of filling in an error. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
40942affe9
commit
09ed6077f9
2 changed files with 22 additions and 7 deletions
|
@ -1,11 +1,24 @@
|
|||
package client
|
||||
|
||||
import apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||
import (
|
||||
"errors"
|
||||
|
||||
apistatus "github.com/nspcc-dev/neofs-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
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// IsErrContainerNotFound checks if err corresponds to NeoFS status
|
||||
// return corresponding to missing container.
|
||||
// return corresponding to missing container. Supports wrapped errors.
|
||||
func IsErrContainerNotFound(err error) bool {
|
||||
switch err.(type) {
|
||||
switch unwrapErr(err).(type) {
|
||||
default:
|
||||
return false
|
||||
case
|
||||
|
@ -16,9 +29,9 @@ func IsErrContainerNotFound(err error) bool {
|
|||
}
|
||||
|
||||
// IsErrObjectNotFound checks if err corresponds to NeoFS status
|
||||
// return corresponding to missing object.
|
||||
// return corresponding to missing object. Supports wrapped errors.
|
||||
func IsErrObjectNotFound(err error) bool {
|
||||
switch err.(type) {
|
||||
switch unwrapErr(err).(type) {
|
||||
default:
|
||||
return false
|
||||
case
|
||||
|
@ -29,9 +42,9 @@ func IsErrObjectNotFound(err error) bool {
|
|||
}
|
||||
|
||||
// IsErrObjectAlreadyRemoved checks if err corresponds to NeoFS status
|
||||
// return corresponding to already removed object.
|
||||
// return corresponding to already removed object. Supports wrapped errors.
|
||||
func IsErrObjectAlreadyRemoved(err error) bool {
|
||||
switch err.(type) {
|
||||
switch unwrapErr(err).(type) {
|
||||
default:
|
||||
return false
|
||||
case
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package client_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neofs-sdk-go/client"
|
||||
|
@ -39,6 +40,7 @@ func TestErrors(t *testing.T) {
|
|||
|
||||
for i := range tc.errs {
|
||||
require.True(t, tc.check(tc.errs[i]), tc.errs[i])
|
||||
require.True(t, tc.check(fmt.Errorf("some context: %w", tc.errs[i])), tc.errs[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue