forked from TrueCloudLab/frostfs-sdk-go
client: Define separate errors instead of IsErrXXX functions
Signed-off-by: Evgenii Baidakov <evgenii@nspcc.io>
This commit is contained in:
parent
8ed98d6dec
commit
7d2cfff825
4 changed files with 112 additions and 22 deletions
|
@ -4,65 +4,68 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/client"
|
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestErrors(t *testing.T) {
|
func TestErrors(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
check func(error) bool
|
errs []error
|
||||||
errs []error
|
errVariable error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
check: client.IsErrContainerNotFound,
|
|
||||||
errs: []error{
|
errs: []error{
|
||||||
apistatus.ContainerNotFound{},
|
apistatus.ContainerNotFound{},
|
||||||
new(apistatus.ContainerNotFound),
|
new(apistatus.ContainerNotFound),
|
||||||
},
|
},
|
||||||
|
errVariable: apistatus.ErrContainerNotFound,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
check: client.IsErrEACLNotFound,
|
|
||||||
errs: []error{
|
errs: []error{
|
||||||
apistatus.EACLNotFound{},
|
apistatus.EACLNotFound{},
|
||||||
new(apistatus.EACLNotFound),
|
new(apistatus.EACLNotFound),
|
||||||
},
|
},
|
||||||
|
errVariable: apistatus.ErrEACLNotFound,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
check: client.IsErrObjectNotFound,
|
|
||||||
errs: []error{
|
errs: []error{
|
||||||
apistatus.ObjectNotFound{},
|
apistatus.ObjectNotFound{},
|
||||||
new(apistatus.ObjectNotFound),
|
new(apistatus.ObjectNotFound),
|
||||||
},
|
},
|
||||||
|
errVariable: apistatus.ErrObjectNotFound,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
check: client.IsErrObjectAlreadyRemoved,
|
|
||||||
errs: []error{
|
errs: []error{
|
||||||
apistatus.ObjectAlreadyRemoved{},
|
apistatus.ObjectAlreadyRemoved{},
|
||||||
new(apistatus.ObjectAlreadyRemoved),
|
new(apistatus.ObjectAlreadyRemoved),
|
||||||
},
|
},
|
||||||
|
errVariable: apistatus.ErrObjectAlreadyRemoved,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
check: client.IsErrSessionExpired,
|
|
||||||
errs: []error{
|
errs: []error{
|
||||||
apistatus.SessionTokenExpired{},
|
apistatus.SessionTokenExpired{},
|
||||||
new(apistatus.SessionTokenExpired),
|
new(apistatus.SessionTokenExpired),
|
||||||
},
|
},
|
||||||
|
errVariable: apistatus.ErrSessionTokenExpired,
|
||||||
}, {
|
}, {
|
||||||
check: client.IsErrSessionNotFound,
|
|
||||||
errs: []error{
|
errs: []error{
|
||||||
apistatus.SessionTokenNotFound{},
|
apistatus.SessionTokenNotFound{},
|
||||||
new(apistatus.SessionTokenNotFound),
|
new(apistatus.SessionTokenNotFound),
|
||||||
},
|
},
|
||||||
|
errVariable: apistatus.ErrSessionTokenNotFound,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
require.NotEmpty(t, tc.errs)
|
require.NotEmpty(t, tc.errs)
|
||||||
|
require.NotNil(t, tc.errVariable)
|
||||||
|
|
||||||
for i := range tc.errs {
|
for i := range tc.errs {
|
||||||
require.True(t, tc.check(tc.errs[i]), tc.errs[i])
|
require.ErrorIs(t, tc.errs[i], tc.errVariable)
|
||||||
require.True(t, tc.check(fmt.Errorf("top-level context: :%w",
|
|
||||||
fmt.Errorf("inner context: %w", tc.errs[i])),
|
wrapped := fmt.Errorf("some message %w", tc.errs[i])
|
||||||
), tc.errs[i])
|
require.ErrorIs(t, wrapped, tc.errVariable)
|
||||||
|
|
||||||
|
wrappedTwice := fmt.Errorf("another message %w", wrapped)
|
||||||
|
require.ErrorIs(t, wrappedTwice, tc.errVariable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,17 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/status"
|
"github.com/nspcc-dev/neofs-api-go/v2/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrEACLNotFound is an instance of EACLNotFound error status. It's expected to be used for [errors.Is]
|
||||||
|
// and MUST NOT be changed.
|
||||||
|
ErrEACLNotFound EACLNotFound
|
||||||
|
// ErrContainerNotFound is an instance of ContainerNotFound error status. It's expected to be used for [errors.Is]
|
||||||
|
// and MUST NOT be changed.
|
||||||
|
ErrContainerNotFound ContainerNotFound
|
||||||
|
)
|
||||||
|
|
||||||
// ContainerNotFound describes status of the failure because of the missing container.
|
// ContainerNotFound describes status of the failure because of the missing container.
|
||||||
// Instances provide Status and StatusV2 interfaces.
|
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||||
type ContainerNotFound struct {
|
type ContainerNotFound struct {
|
||||||
v2 status.Status
|
v2 status.Status
|
||||||
}
|
}
|
||||||
|
@ -25,6 +34,16 @@ func (x ContainerNotFound) Error() string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is implements interface for correct checking current error type with [errors.Is].
|
||||||
|
func (x ContainerNotFound) Is(target error) bool {
|
||||||
|
switch target.(type) {
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
case ContainerNotFound, *ContainerNotFound:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// implements local interface defined in FromStatusV2 func.
|
// implements local interface defined in FromStatusV2 func.
|
||||||
func (x *ContainerNotFound) fromStatusV2(st *status.Status) {
|
func (x *ContainerNotFound) fromStatusV2(st *status.Status) {
|
||||||
x.v2 = *st
|
x.v2 = *st
|
||||||
|
@ -44,7 +63,7 @@ func (x ContainerNotFound) ToStatusV2() *status.Status {
|
||||||
|
|
||||||
// EACLNotFound describes status of the failure because of the missing eACL
|
// EACLNotFound describes status of the failure because of the missing eACL
|
||||||
// table.
|
// table.
|
||||||
// Instances provide Status and StatusV2 interfaces.
|
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||||
type EACLNotFound struct {
|
type EACLNotFound struct {
|
||||||
v2 status.Status
|
v2 status.Status
|
||||||
}
|
}
|
||||||
|
@ -63,6 +82,16 @@ func (x EACLNotFound) Error() string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is implements interface for correct checking current error type with [errors.Is].
|
||||||
|
func (x EACLNotFound) Is(target error) bool {
|
||||||
|
switch target.(type) {
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
case EACLNotFound, *EACLNotFound:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// implements local interface defined in FromStatusV2 func.
|
// implements local interface defined in FromStatusV2 func.
|
||||||
func (x *EACLNotFound) fromStatusV2(st *status.Status) {
|
func (x *EACLNotFound) fromStatusV2(st *status.Status) {
|
||||||
x.v2 = *st
|
x.v2 = *st
|
||||||
|
|
|
@ -5,8 +5,17 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/status"
|
"github.com/nspcc-dev/neofs-api-go/v2/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrObjectAlreadyRemoved is an instance of ObjectAlreadyRemoved error status. It's expected to be used for [errors.Is]
|
||||||
|
// and MUST NOT be changed.
|
||||||
|
ErrObjectAlreadyRemoved ObjectAlreadyRemoved
|
||||||
|
// ErrObjectNotFound is an instance of ObjectNotFound error status. It's expected to be used for [errors.Is]
|
||||||
|
// and MUST NOT be changed.
|
||||||
|
ErrObjectNotFound ObjectNotFound
|
||||||
|
)
|
||||||
|
|
||||||
// ObjectLocked describes status of the failure because of the locked object.
|
// ObjectLocked describes status of the failure because of the locked object.
|
||||||
// Instances provide Status and StatusV2 interfaces.
|
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||||
type ObjectLocked struct {
|
type ObjectLocked struct {
|
||||||
v2 status.Status
|
v2 status.Status
|
||||||
}
|
}
|
||||||
|
@ -43,7 +52,7 @@ func (x ObjectLocked) ToStatusV2() *status.Status {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LockNonRegularObject describes status returned on locking the non-regular object.
|
// LockNonRegularObject describes status returned on locking the non-regular object.
|
||||||
// Instances provide Status and StatusV2 interfaces.
|
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||||
type LockNonRegularObject struct {
|
type LockNonRegularObject struct {
|
||||||
v2 status.Status
|
v2 status.Status
|
||||||
}
|
}
|
||||||
|
@ -80,7 +89,7 @@ func (x LockNonRegularObject) ToStatusV2() *status.Status {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectAccessDenied describes status of the failure because of the access control violation.
|
// ObjectAccessDenied describes status of the failure because of the access control violation.
|
||||||
// Instances provide Status and StatusV2 interfaces.
|
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||||
type ObjectAccessDenied struct {
|
type ObjectAccessDenied struct {
|
||||||
v2 status.Status
|
v2 status.Status
|
||||||
}
|
}
|
||||||
|
@ -128,7 +137,7 @@ func (x ObjectAccessDenied) Reason() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectNotFound describes status of the failure because of the missing object.
|
// ObjectNotFound describes status of the failure because of the missing object.
|
||||||
// Instances provide Status and StatusV2 interfaces.
|
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||||
type ObjectNotFound struct {
|
type ObjectNotFound struct {
|
||||||
v2 status.Status
|
v2 status.Status
|
||||||
}
|
}
|
||||||
|
@ -147,6 +156,16 @@ func (x ObjectNotFound) Error() string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is implements interface for correct checking current error type with [errors.Is].
|
||||||
|
func (x ObjectNotFound) Is(target error) bool {
|
||||||
|
switch target.(type) {
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
case ObjectNotFound, *ObjectNotFound:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// implements local interface defined in FromStatusV2 func.
|
// implements local interface defined in FromStatusV2 func.
|
||||||
func (x *ObjectNotFound) fromStatusV2(st *status.Status) {
|
func (x *ObjectNotFound) fromStatusV2(st *status.Status) {
|
||||||
x.v2 = *st
|
x.v2 = *st
|
||||||
|
@ -184,6 +203,16 @@ func (x ObjectAlreadyRemoved) Error() string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is implements interface for correct checking current error type with [errors.Is].
|
||||||
|
func (x ObjectAlreadyRemoved) Is(target error) bool {
|
||||||
|
switch target.(type) {
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
case ObjectAlreadyRemoved, *ObjectAlreadyRemoved:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// implements local interface defined in FromStatusV2 func.
|
// implements local interface defined in FromStatusV2 func.
|
||||||
func (x *ObjectAlreadyRemoved) fromStatusV2(st *status.Status) {
|
func (x *ObjectAlreadyRemoved) fromStatusV2(st *status.Status) {
|
||||||
x.v2 = *st
|
x.v2 = *st
|
||||||
|
@ -203,7 +232,7 @@ func (x ObjectAlreadyRemoved) ToStatusV2() *status.Status {
|
||||||
|
|
||||||
// ObjectOutOfRange describes status of the failure because of the incorrect
|
// ObjectOutOfRange describes status of the failure because of the incorrect
|
||||||
// provided object ranges.
|
// provided object ranges.
|
||||||
// Instances provide Status and StatusV2 interfaces.
|
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||||
type ObjectOutOfRange struct {
|
type ObjectOutOfRange struct {
|
||||||
v2 status.Status
|
v2 status.Status
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,17 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/status"
|
"github.com/nspcc-dev/neofs-api-go/v2/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrSessionTokenNotFound is an instance of SessionTokenNotFound error status. It's expected to be used for [errors.Is]
|
||||||
|
// and MUST NOT be changed.
|
||||||
|
ErrSessionTokenNotFound SessionTokenNotFound
|
||||||
|
// ErrSessionTokenExpired is an instance of SessionTokenExpired error status. It's expected to be used for [errors.Is]
|
||||||
|
// and MUST NOT be changed.
|
||||||
|
ErrSessionTokenExpired SessionTokenExpired
|
||||||
|
)
|
||||||
|
|
||||||
// SessionTokenNotFound describes status of the failure because of the missing session token.
|
// SessionTokenNotFound describes status of the failure because of the missing session token.
|
||||||
// Instances provide Status and StatusV2 interfaces.
|
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||||
type SessionTokenNotFound struct {
|
type SessionTokenNotFound struct {
|
||||||
v2 status.Status
|
v2 status.Status
|
||||||
}
|
}
|
||||||
|
@ -25,6 +34,16 @@ func (x SessionTokenNotFound) Error() string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is implements interface for correct checking current error type with [errors.Is].
|
||||||
|
func (x SessionTokenNotFound) Is(target error) bool {
|
||||||
|
switch target.(type) {
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
case SessionTokenNotFound, *SessionTokenNotFound:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// implements local interface defined in FromStatusV2 func.
|
// implements local interface defined in FromStatusV2 func.
|
||||||
func (x *SessionTokenNotFound) fromStatusV2(st *status.Status) {
|
func (x *SessionTokenNotFound) fromStatusV2(st *status.Status) {
|
||||||
x.v2 = *st
|
x.v2 = *st
|
||||||
|
@ -43,7 +62,7 @@ func (x SessionTokenNotFound) ToStatusV2() *status.Status {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SessionTokenExpired describes status of the failure because of the expired session token.
|
// SessionTokenExpired describes status of the failure because of the expired session token.
|
||||||
// Instances provide Status and StatusV2 interfaces.
|
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||||
type SessionTokenExpired struct {
|
type SessionTokenExpired struct {
|
||||||
v2 status.Status
|
v2 status.Status
|
||||||
}
|
}
|
||||||
|
@ -62,6 +81,16 @@ func (x SessionTokenExpired) Error() string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is implements interface for correct checking current error type with [errors.Is].
|
||||||
|
func (x SessionTokenExpired) Is(target error) bool {
|
||||||
|
switch target.(type) {
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
case SessionTokenExpired, *SessionTokenExpired:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// implements local interface defined in FromStatusV2 func.
|
// implements local interface defined in FromStatusV2 func.
|
||||||
func (x *SessionTokenExpired) fromStatusV2(st *status.Status) {
|
func (x *SessionTokenExpired) fromStatusV2(st *status.Status) {
|
||||||
x.v2 = *st
|
x.v2 = *st
|
||||||
|
|
Loading…
Reference in a new issue