forked from TrueCloudLab/frostfs-sdk-go
commit
4d4c5fc70c
21 changed files with 163 additions and 303 deletions
|
@ -197,23 +197,17 @@ func (x *contextCall) processResponse() bool {
|
|||
}
|
||||
|
||||
// get result status
|
||||
st := apistatus.FromStatusV2(x.resp.GetMetaHeader().GetStatus())
|
||||
|
||||
successfulStatus := apistatus.IsSuccessful(st)
|
||||
x.err = apistatus.ErrFromStatus(st)
|
||||
|
||||
return successfulStatus
|
||||
x.err = apistatus.ErrorFromV2(x.resp.GetMetaHeader().GetStatus())
|
||||
return x.err == nil
|
||||
}
|
||||
|
||||
// processResponse verifies response signature.
|
||||
func (c *Client) processResponse(resp responseV2) (apistatus.Status, error) {
|
||||
err := verifyServiceMessage(resp)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid response signature: %w", err)
|
||||
func (c *Client) processResponse(resp responseV2) error {
|
||||
if err := verifyServiceMessage(resp); err != nil {
|
||||
return fmt.Errorf("invalid response signature: %w", err)
|
||||
}
|
||||
|
||||
st := apistatus.FromStatusV2(resp.GetMetaHeader().GetStatus())
|
||||
return st, apistatus.ErrFromStatus(st)
|
||||
return apistatus.ErrorFromV2(resp.GetMetaHeader().GetStatus())
|
||||
}
|
||||
|
||||
// reads response (if rResp is set) and processes it. Result means success.
|
||||
|
|
|
@ -217,8 +217,7 @@ func (c *Client) NetMapSnapshot(ctx context.Context, _ PrmNetMapSnapshot) (*ResN
|
|||
}
|
||||
|
||||
var res ResNetMapSnapshot
|
||||
_, err = c.processResponse(resp)
|
||||
if err != nil {
|
||||
if err = c.processResponse(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ func (x *serverNetMap) netMapSnapshot(_ context.Context, req v2netmap.SnapshotRe
|
|||
var meta session.ResponseMetaHeader
|
||||
|
||||
if !x.statusOK {
|
||||
meta.SetStatus(statusErr.ToStatusV2())
|
||||
meta.SetStatus(statusErr.ErrorToV2())
|
||||
}
|
||||
|
||||
var resp v2netmap.SnapshotResponse
|
||||
|
|
|
@ -156,8 +156,7 @@ func (c *Client) ObjectDelete(ctx context.Context, prm PrmObjectDelete) (*ResObj
|
|||
}
|
||||
|
||||
var res ResObjectDelete
|
||||
_, err = c.processResponse(resp)
|
||||
if err != nil {
|
||||
if err = c.processResponse(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ func (x *ObjectReader) ReadHeader(dst *object.Object) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
_, x.err = x.client.processResponse(&resp)
|
||||
x.err = x.client.processResponse(&resp)
|
||||
if x.err != nil {
|
||||
return false
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ func (x *ObjectReader) readChunk(buf []byte) (int, bool) {
|
|||
return read, false
|
||||
}
|
||||
|
||||
_, x.err = x.client.processResponse(&resp)
|
||||
x.err = x.client.processResponse(&resp)
|
||||
if x.err != nil {
|
||||
return read, false
|
||||
}
|
||||
|
@ -433,8 +433,7 @@ func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectH
|
|||
}
|
||||
|
||||
var res ResObjectHead
|
||||
_, err = c.processResponse(resp)
|
||||
if err != nil {
|
||||
if err = c.processResponse(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -529,7 +528,7 @@ func (x *ObjectRangeReader) readChunk(buf []byte) (int, bool) {
|
|||
return read, false
|
||||
}
|
||||
|
||||
_, x.err = x.client.processResponse(&resp)
|
||||
x.err = x.client.processResponse(&resp)
|
||||
if x.err != nil {
|
||||
return read, false
|
||||
}
|
||||
|
|
|
@ -195,8 +195,7 @@ func (c *Client) ObjectHash(ctx context.Context, prm PrmObjectHash) (*ResObjectH
|
|||
}
|
||||
|
||||
var res ResObjectHash
|
||||
_, err = c.processResponse(resp)
|
||||
if err != nil {
|
||||
if err = c.processResponse(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
|
||||
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||
|
@ -206,8 +205,7 @@ func (x *ObjectWriter) Close() (*ResObjectPut, error) {
|
|||
return nil, x.err
|
||||
}
|
||||
|
||||
_, x.err = x.client.processResponse(&x.respV2)
|
||||
if x.err != nil {
|
||||
if x.err = x.client.processResponse(&x.respV2); x.err != nil {
|
||||
return nil, x.err
|
||||
}
|
||||
|
||||
|
@ -275,12 +273,12 @@ func (x *objectWriter) InitDataStream(header object.Object) (io.Writer, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
res, err := stream.Close()
|
||||
_, err = stream.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, apistatus.ErrFromStatus(res)
|
||||
return nil, errors.New("unexpected error")
|
||||
}
|
||||
|
||||
type payloadWriter struct {
|
||||
|
@ -296,12 +294,12 @@ func (x *payloadWriter) Write(p []byte) (int, error) {
|
|||
}
|
||||
|
||||
func (x *payloadWriter) Close() error {
|
||||
res, err := x.stream.Close()
|
||||
_, err := x.stream.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return apistatus.ErrFromStatus(res)
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateObject creates new NeoFS object with given payload data and stores it
|
||||
|
|
|
@ -125,7 +125,7 @@ func (x *ObjectListReader) Read(buf []oid.ID) (int, bool) {
|
|||
return read, false
|
||||
}
|
||||
|
||||
_, x.err = x.client.processResponse(&resp)
|
||||
x.err = x.client.processResponse(&resp)
|
||||
if x.err != nil {
|
||||
return read, false
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ var (
|
|||
)
|
||||
|
||||
// ServerInternal describes failure statuses related to internal server errors.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
//
|
||||
// The status is purely informative, the client should not go into details of the error except for debugging needs.
|
||||
type ServerInternal struct {
|
||||
|
@ -51,18 +51,18 @@ func (x ServerInternal) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *ServerInternal) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: INTERNAL;
|
||||
// - string message: empty;
|
||||
// - details: empty.
|
||||
func (x ServerInternal) ToStatusV2() *status.Status {
|
||||
func (x ServerInternal) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(status.Internal, status.GlobalizeCommonFail))
|
||||
return &x.v2
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func WriteInternalServerErr(x *ServerInternal, err error) {
|
|||
}
|
||||
|
||||
// WrongMagicNumber describes failure status related to incorrect network magic.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type WrongMagicNumber struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -109,18 +109,18 @@ func (x WrongMagicNumber) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *WrongMagicNumber) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: WRONG_MAGIC_NUMBER;
|
||||
// - string message: empty;
|
||||
// - details: empty.
|
||||
func (x WrongMagicNumber) ToStatusV2() *status.Status {
|
||||
func (x WrongMagicNumber) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(status.WrongMagicNumber, status.GlobalizeCommonFail))
|
||||
return &x.v2
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ func (x WrongMagicNumber) CorrectMagic() (magic uint64, ok int8) {
|
|||
}
|
||||
|
||||
// SignatureVerification describes failure status related to signature verification.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type SignatureVerification struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -194,19 +194,19 @@ func (x SignatureVerification) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *SignatureVerification) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: SIGNATURE_VERIFICATION_FAIL;
|
||||
// - string message: written message via SetMessage or
|
||||
// - string message: written message via [SignatureVerification.SetMessage] or
|
||||
// "signature verification failed" as a default message;
|
||||
// - details: empty.
|
||||
func (x SignatureVerification) ToStatusV2() *status.Status {
|
||||
func (x SignatureVerification) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(status.SignatureVerificationFail, status.GlobalizeCommonFail))
|
||||
|
||||
if x.v2.Message() == "" {
|
||||
|
@ -233,7 +233,7 @@ func (x SignatureVerification) Message() string {
|
|||
}
|
||||
|
||||
// NodeUnderMaintenance describes failure status for nodes being under maintenance.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type NodeUnderMaintenance struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -267,14 +267,14 @@ func (x *NodeUnderMaintenance) fromStatusV2(st *status.Status) {
|
|||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: NODE_UNDER_MAINTENANCE;
|
||||
// - string message: written message via SetMessage or
|
||||
// - string message: written message via [NodeUnderMaintenance.SetMessage] or
|
||||
// "node is under maintenance" as a default message;
|
||||
// - details: empty.
|
||||
func (x NodeUnderMaintenance) ToStatusV2() *status.Status {
|
||||
func (x NodeUnderMaintenance) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(status.NodeUnderMaintenance, status.GlobalizeCommonFail))
|
||||
if x.v2.Message() == "" {
|
||||
x.v2.SetMessage(defaultNodeUnderMaintenanceMsg)
|
||||
|
|
|
@ -14,14 +14,14 @@ func TestServerInternal_Message(t *testing.T) {
|
|||
var st apistatus.ServerInternal
|
||||
|
||||
res := st.Message()
|
||||
resv2 := apistatus.ToStatusV2(st).Message()
|
||||
resv2 := apistatus.ErrorToV2(st).Message()
|
||||
require.Empty(t, res)
|
||||
require.Empty(t, resv2)
|
||||
|
||||
st.SetMessage(msg)
|
||||
|
||||
res = st.Message()
|
||||
resv2 = apistatus.ToStatusV2(st).Message()
|
||||
resv2 = apistatus.ErrorToV2(st).Message()
|
||||
require.Equal(t, msg, res)
|
||||
require.Equal(t, msg, resv2)
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ func TestWrongMagicNumber_CorrectMagic(t *testing.T) {
|
|||
require.EqualValues(t, 1, ok)
|
||||
|
||||
// corrupt the value
|
||||
apistatus.ToStatusV2(st).IterateDetails(func(d *status.Detail) bool {
|
||||
apistatus.ErrorToV2(st).IterateDetails(func(d *status.Detail) bool {
|
||||
d.SetValue([]byte{1, 2, 3}) // any slice with len != 8
|
||||
return true
|
||||
})
|
||||
|
@ -64,7 +64,7 @@ func TestSignatureVerification(t *testing.T) {
|
|||
|
||||
st.SetMessage(msg)
|
||||
|
||||
stV2 := st.ToStatusV2()
|
||||
stV2 := st.ErrorToV2()
|
||||
|
||||
require.Equal(t, msg, st.Message())
|
||||
require.Equal(t, msg, stV2.Message())
|
||||
|
@ -73,7 +73,7 @@ func TestSignatureVerification(t *testing.T) {
|
|||
t.Run("empty to V2", func(t *testing.T) {
|
||||
var st apistatus.SignatureVerification
|
||||
|
||||
stV2 := st.ToStatusV2()
|
||||
stV2 := st.ErrorToV2()
|
||||
|
||||
require.Equal(t, "signature verification failed", stV2.Message())
|
||||
})
|
||||
|
@ -84,7 +84,7 @@ func TestSignatureVerification(t *testing.T) {
|
|||
|
||||
st.SetMessage(msg)
|
||||
|
||||
stV2 := st.ToStatusV2()
|
||||
stV2 := st.ErrorToV2()
|
||||
|
||||
require.Equal(t, msg, stV2.Message())
|
||||
})
|
||||
|
@ -103,7 +103,7 @@ func TestNodeUnderMaintenance(t *testing.T) {
|
|||
|
||||
st.SetMessage(msg)
|
||||
|
||||
stV2 := st.ToStatusV2()
|
||||
stV2 := st.ErrorToV2()
|
||||
|
||||
require.Equal(t, msg, st.Message())
|
||||
require.Equal(t, msg, stV2.Message())
|
||||
|
@ -112,7 +112,7 @@ func TestNodeUnderMaintenance(t *testing.T) {
|
|||
t.Run("empty to V2", func(t *testing.T) {
|
||||
var st apistatus.NodeUnderMaintenance
|
||||
|
||||
stV2 := st.ToStatusV2()
|
||||
stV2 := st.ErrorToV2()
|
||||
|
||||
require.Empty(t, "", stV2.Message())
|
||||
})
|
||||
|
@ -123,7 +123,7 @@ func TestNodeUnderMaintenance(t *testing.T) {
|
|||
|
||||
st.SetMessage(msg)
|
||||
|
||||
stV2 := st.ToStatusV2()
|
||||
stV2 := st.ErrorToV2()
|
||||
|
||||
require.Equal(t, msg, stV2.Message())
|
||||
})
|
||||
|
|
|
@ -17,7 +17,7 @@ var (
|
|||
)
|
||||
|
||||
// ContainerNotFound describes status of the failure because of the missing container.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type ContainerNotFound struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -46,18 +46,18 @@ func (x ContainerNotFound) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *ContainerNotFound) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: CONTAINER_NOT_FOUND;
|
||||
// - string message: "container not found";
|
||||
// - details: empty.
|
||||
func (x ContainerNotFound) ToStatusV2() *status.Status {
|
||||
func (x ContainerNotFound) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(container.StatusNotFound, container.GlobalizeFail))
|
||||
x.v2.SetMessage(defaultContainerNotFoundMsg)
|
||||
return &x.v2
|
||||
|
@ -65,7 +65,7 @@ func (x ContainerNotFound) ToStatusV2() *status.Status {
|
|||
|
||||
// EACLNotFound describes status of the failure because of the missing eACL
|
||||
// table.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type EACLNotFound struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -94,18 +94,18 @@ func (x EACLNotFound) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *EACLNotFound) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: EACL_NOT_FOUND;
|
||||
// - string message: "eACL not found";
|
||||
// - details: empty.
|
||||
func (x EACLNotFound) ToStatusV2() *status.Status {
|
||||
func (x EACLNotFound) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(container.StatusEACLNotFound, container.GlobalizeFail))
|
||||
x.v2.SetMessage(defaultEACLNotFoundMsg)
|
||||
return &x.v2
|
||||
|
|
|
@ -29,7 +29,7 @@ var (
|
|||
)
|
||||
|
||||
// ObjectLocked describes status of the failure because of the locked object.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type ObjectLocked struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -58,25 +58,25 @@ func (x ObjectLocked) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *ObjectLocked) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: LOCKED;
|
||||
// - string message: "object is locked";
|
||||
// - details: empty.
|
||||
func (x ObjectLocked) ToStatusV2() *status.Status {
|
||||
func (x ObjectLocked) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(object.StatusLocked, object.GlobalizeFail))
|
||||
x.v2.SetMessage(defaultObjectLockedMsg)
|
||||
return &x.v2
|
||||
}
|
||||
|
||||
// LockNonRegularObject describes status returned on locking the non-regular object.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type LockNonRegularObject struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -105,25 +105,25 @@ func (x LockNonRegularObject) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *LockNonRegularObject) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: LOCK_NON_REGULAR_OBJECT;
|
||||
// - string message: "locking non-regular object is forbidden";
|
||||
// - details: empty.
|
||||
func (x LockNonRegularObject) ToStatusV2() *status.Status {
|
||||
func (x LockNonRegularObject) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(object.StatusLockNonRegularObject, object.GlobalizeFail))
|
||||
x.v2.SetMessage(defaultLockNonRegularObjectMsg)
|
||||
return &x.v2
|
||||
}
|
||||
|
||||
// ObjectAccessDenied describes status of the failure because of the access control violation.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type ObjectAccessDenied struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -152,18 +152,18 @@ func (x ObjectAccessDenied) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *ObjectAccessDenied) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: ACCESS_DENIED;
|
||||
// - string message: "access to object operation denied";
|
||||
// - details: empty.
|
||||
func (x ObjectAccessDenied) ToStatusV2() *status.Status {
|
||||
func (x ObjectAccessDenied) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(object.StatusAccessDenied, object.GlobalizeFail))
|
||||
x.v2.SetMessage(defaultObjectAccessDeniedMsg)
|
||||
return &x.v2
|
||||
|
@ -181,7 +181,7 @@ func (x ObjectAccessDenied) Reason() string {
|
|||
}
|
||||
|
||||
// ObjectNotFound describes status of the failure because of the missing object.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type ObjectNotFound struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -210,18 +210,18 @@ func (x ObjectNotFound) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *ObjectNotFound) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: OBJECT_NOT_FOUND;
|
||||
// - string message: "object not found";
|
||||
// - details: empty.
|
||||
func (x ObjectNotFound) ToStatusV2() *status.Status {
|
||||
func (x ObjectNotFound) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(object.StatusNotFound, object.GlobalizeFail))
|
||||
x.v2.SetMessage(defaultObjectNotFoundMsg)
|
||||
return &x.v2
|
||||
|
@ -257,18 +257,18 @@ func (x ObjectAlreadyRemoved) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *ObjectAlreadyRemoved) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: OBJECT_ALREADY_REMOVED;
|
||||
// - string message: "object already removed";
|
||||
// - details: empty.
|
||||
func (x ObjectAlreadyRemoved) ToStatusV2() *status.Status {
|
||||
func (x ObjectAlreadyRemoved) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(object.StatusAlreadyRemoved, object.GlobalizeFail))
|
||||
x.v2.SetMessage(defaultObjectAlreadyRemovedMsg)
|
||||
return &x.v2
|
||||
|
@ -276,7 +276,7 @@ func (x ObjectAlreadyRemoved) ToStatusV2() *status.Status {
|
|||
|
||||
// ObjectOutOfRange describes status of the failure because of the incorrect
|
||||
// provided object ranges.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type ObjectOutOfRange struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -305,18 +305,18 @@ func (x ObjectOutOfRange) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *ObjectOutOfRange) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: OUT_OF_RANGE;
|
||||
// - string message: "out of range";
|
||||
// - details: empty.
|
||||
func (x ObjectOutOfRange) ToStatusV2() *status.Status {
|
||||
func (x ObjectOutOfRange) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(object.StatusOutOfRange, object.GlobalizeFail))
|
||||
x.v2.SetMessage(defaultObjectOutOfRangeMsg)
|
||||
return &x.v2
|
||||
|
|
|
@ -14,13 +14,13 @@ func TestObjectAccessDenied_WriteReason(t *testing.T) {
|
|||
|
||||
res := st.Reason()
|
||||
require.Empty(t, res)
|
||||
detailNum := apistatus.ToStatusV2(st).NumberOfDetails()
|
||||
detailNum := apistatus.ErrorToV2(st).NumberOfDetails()
|
||||
require.Zero(t, detailNum)
|
||||
|
||||
st.WriteReason(reason)
|
||||
|
||||
res = st.Reason()
|
||||
require.Equal(t, reason, res)
|
||||
detailNum = apistatus.ToStatusV2(st).NumberOfDetails()
|
||||
detailNum = apistatus.ErrorToV2(st).NumberOfDetails()
|
||||
require.EqualValues(t, 1, detailNum)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ var (
|
|||
)
|
||||
|
||||
// SessionTokenNotFound describes status of the failure because of the missing session token.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type SessionTokenNotFound struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -46,25 +46,25 @@ func (x SessionTokenNotFound) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *SessionTokenNotFound) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: TOKEN_NOT_FOUND;
|
||||
// - string message: "session token not found";
|
||||
// - details: empty.
|
||||
func (x SessionTokenNotFound) ToStatusV2() *status.Status {
|
||||
func (x SessionTokenNotFound) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(session.StatusTokenNotFound, session.GlobalizeFail))
|
||||
x.v2.SetMessage(defaultSessionTokenNotFoundMsg)
|
||||
return &x.v2
|
||||
}
|
||||
|
||||
// SessionTokenExpired describes status of the failure because of the expired session token.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type SessionTokenExpired struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -93,18 +93,18 @@ func (x SessionTokenExpired) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *SessionTokenExpired) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// ErrorToV2 implements [StatusV2] interface method.
|
||||
// If the value was returned by [ErrorFromV2], returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: TOKEN_EXPIRED;
|
||||
// - string message: "expired session token";
|
||||
// - details: empty.
|
||||
func (x SessionTokenExpired) ToStatusV2() *status.Status {
|
||||
func (x SessionTokenExpired) ErrorToV2() *status.Status {
|
||||
x.v2.SetCode(globalizeCodeV2(session.StatusTokenExpired, session.GlobalizeFail))
|
||||
x.v2.SetMessage(defaultSessionTokenExpiredMsg)
|
||||
return &x.v2
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
package apistatus
|
||||
|
||||
// Status defines a variety of NeoFS API status returns.
|
||||
//
|
||||
// All statuses are split into two disjoint subsets: successful and failed, and:
|
||||
// - statuses that implement the build-in error interface are considered failed statuses;
|
||||
// - all other value types are considered successes (nil is a default success).
|
||||
//
|
||||
// In Go code type of success can be determined by a type switch, failure - by a switch with errors.As calls.
|
||||
// Nil should be considered as a success, and default switch section - as an unrecognized Status.
|
||||
//
|
||||
// To convert statuses into errors and vice versa, use functions ErrToStatus and ErrFromStatus, respectively.
|
||||
// ErrFromStatus function returns nil for successful statuses. However, to simplify the check of statuses for success,
|
||||
// IsSuccessful function should be used (try to avoid nil comparison).
|
||||
// It should be noted that using direct typecasting is not a compatible approach.
|
||||
//
|
||||
// To transport statuses using the NeoFS API V2 protocol, see StatusV2 interface and FromStatusV2 and ToStatusV2 functions.
|
||||
type Status any
|
||||
|
||||
// ErrFromStatus converts Status instance to error if it is failed. Returns nil on successful Status.
|
||||
//
|
||||
// Note: direct assignment may not be compatibility-safe.
|
||||
func ErrFromStatus(st Status) error {
|
||||
if err, ok := st.(error); ok {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ErrToStatus converts the error instance to Status instance.
|
||||
//
|
||||
// Note: direct assignment may not be compatibility-safe.
|
||||
func ErrToStatus(err error) Status {
|
||||
return err
|
||||
}
|
||||
|
||||
// IsSuccessful checks if status is successful.
|
||||
//
|
||||
// Note: direct cast may not be compatibility-safe.
|
||||
func IsSuccessful(st Status) bool {
|
||||
_, ok := st.(error)
|
||||
return !ok
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package apistatus_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
t.Run("error source", func(t *testing.T) {
|
||||
err := errors.New("some error")
|
||||
|
||||
st := apistatus.ErrToStatus(err)
|
||||
|
||||
success := apistatus.IsSuccessful(st)
|
||||
require.False(t, success)
|
||||
|
||||
res := apistatus.ErrFromStatus(st)
|
||||
|
||||
require.ErrorIs(t, res, err)
|
||||
})
|
||||
|
||||
t.Run("non-error source", func(t *testing.T) {
|
||||
var st apistatus.Status = "any non-error type"
|
||||
|
||||
success := apistatus.IsSuccessful(st)
|
||||
require.True(t, success)
|
||||
|
||||
res := apistatus.ErrFromStatus(st)
|
||||
|
||||
require.Nil(t, res)
|
||||
})
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package apistatus
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/status"
|
||||
)
|
||||
|
||||
// SuccessDefaultV2 represents Status instance of default success. Implements StatusV2.
|
||||
type SuccessDefaultV2 struct {
|
||||
isNil bool
|
||||
|
||||
v2 *status.Status
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
func (x *SuccessDefaultV2) fromStatusV2(st *status.Status) {
|
||||
x.isNil = st == nil
|
||||
x.v2 = st
|
||||
}
|
||||
|
||||
// ToStatusV2 implements StatusV2 interface method.
|
||||
// If the value was returned by FromStatusV2, returns the source message.
|
||||
// Otherwise, returns message with
|
||||
// - code: OK;
|
||||
// - string message: empty;
|
||||
// - details: empty.
|
||||
func (x SuccessDefaultV2) ToStatusV2() *status.Status {
|
||||
if x.isNil || x.v2 != nil {
|
||||
return x.v2
|
||||
}
|
||||
|
||||
return newStatusV2WithLocalCode(status.OK, status.GlobalizeSuccess)
|
||||
}
|
|
@ -9,7 +9,7 @@ import (
|
|||
var ErrUnrecognizedStatusV2 UnrecognizedStatusV2
|
||||
|
||||
// UnrecognizedStatusV2 describes status of the uncertain failure.
|
||||
// Instances provide [Status], [StatusV2] and error interfaces.
|
||||
// Instances provide [StatusV2] and error interfaces.
|
||||
type UnrecognizedStatusV2 struct {
|
||||
v2 status.Status
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func (x UnrecognizedStatusV2) Is(target error) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// implements local interface defined in FromStatusV2 func.
|
||||
// implements local interface defined in [ErrorFromV2] func.
|
||||
func (x *UnrecognizedStatusV2) fromStatusV2(st *status.Status) {
|
||||
x.v2 = *st
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package apistatus
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/container"
|
||||
|
@ -9,26 +10,24 @@ import (
|
|||
"github.com/nspcc-dev/neofs-api-go/v2/status"
|
||||
)
|
||||
|
||||
// StatusV2 defines a variety of Status instances compatible with NeoFS API V2 protocol.
|
||||
// StatusV2 defines a variety of status instances compatible with NeoFS API V2 protocol.
|
||||
//
|
||||
// Note: it is not recommended to use this type directly, it is intended for documentation of the library functionality.
|
||||
type StatusV2 interface {
|
||||
Status
|
||||
|
||||
// ToStatusV2 returns the status as github.com/nspcc-dev/neofs-api-go/v2/status.Status message structure.
|
||||
ToStatusV2() *status.Status
|
||||
// ErrorToV2 returns the status as github.com/nspcc-dev/neofs-api-go/v2/status.Status message structure.
|
||||
ErrorToV2() *status.Status
|
||||
}
|
||||
|
||||
// FromStatusV2 converts status.Status message structure to Status instance. Inverse to ToStatusV2 operation.
|
||||
// ErrorFromV2 converts [status.Status] message structure to error. Inverse to [ErrorToV2] operation.
|
||||
//
|
||||
// If result is not nil, it implements StatusV2. This fact should be taken into account only when passing
|
||||
// the result to the inverse function ToStatusV2, casts are not compatibility-safe.
|
||||
// If result is not nil, it implements [StatusV2]. This fact should be taken into account only when passing
|
||||
// the result to the inverse function [ErrorToV2], casts are not compatibility-safe.
|
||||
//
|
||||
// Below is the mapping of return codes to Status instance types (with a description of parsing details).
|
||||
// Below is the mapping of return codes to status instance types (with a description of parsing details).
|
||||
// Note: notice if the return type is a pointer.
|
||||
//
|
||||
// Successes:
|
||||
// - [status.OK]: *[SuccessDefaultV2] (this also includes nil argument).
|
||||
// - [status.OK]: nil (this also includes nil argument).
|
||||
//
|
||||
// Common failures:
|
||||
// - [status.Internal]: *[ServerInternal];
|
||||
|
@ -51,9 +50,10 @@ type StatusV2 interface {
|
|||
// Session failures:
|
||||
// - [session.StatusTokenNotFound]: *[SessionTokenNotFound];
|
||||
// - [session.StatusTokenExpired]: *[SessionTokenExpired];
|
||||
func FromStatusV2(st *status.Status) Status {
|
||||
func ErrorFromV2(st *status.Status) error {
|
||||
var decoder interface {
|
||||
fromStatusV2(*status.Status)
|
||||
Error() string
|
||||
}
|
||||
|
||||
switch code := st.Code(); {
|
||||
|
@ -61,7 +61,7 @@ func FromStatusV2(st *status.Status) Status {
|
|||
//nolint:exhaustive
|
||||
switch status.LocalizeSuccess(&code); code {
|
||||
case status.OK:
|
||||
decoder = new(SuccessDefaultV2)
|
||||
return nil
|
||||
}
|
||||
case status.IsCommonFail(code):
|
||||
switch status.LocalizeCommonFail(&code); code {
|
||||
|
@ -116,22 +116,23 @@ func FromStatusV2(st *status.Status) Status {
|
|||
return decoder
|
||||
}
|
||||
|
||||
// ToStatusV2 converts Status instance to status.Status message structure. Inverse to FromStatusV2 operation.
|
||||
// ErrorToV2 converts error to status.Status message structure. Inverse to [ErrorFromV2] operation.
|
||||
//
|
||||
// If argument is the StatusV2 instance, it is converted directly.
|
||||
// Otherwise, successes are converted with status.OK code w/o details and message,
|
||||
// failures - with status.Internal and error text message w/o details.
|
||||
func ToStatusV2(st Status) *status.Status {
|
||||
if v, ok := st.(StatusV2); ok {
|
||||
return v.ToStatusV2()
|
||||
}
|
||||
|
||||
if IsSuccessful(st) {
|
||||
// If argument is the [StatusV2] instance, it is converted directly.
|
||||
// Otherwise, successes are converted with [status.OK] code w/o details and message,
|
||||
// failures - with [status.Internal] and error text message w/o details.
|
||||
func ErrorToV2(err error) *status.Status {
|
||||
if err == nil {
|
||||
return newStatusV2WithLocalCode(status.OK, status.GlobalizeSuccess)
|
||||
}
|
||||
|
||||
var instance StatusV2
|
||||
if errors.As(err, &instance) {
|
||||
return instance.ErrorToV2()
|
||||
}
|
||||
|
||||
internalErrorStatus := newStatusV2WithLocalCode(status.Internal, status.GlobalizeCommonFail)
|
||||
internalErrorStatus.SetMessage(st.(error).Error()) // type cast never panics because IsSuccessful() checks cast
|
||||
internalErrorStatus.SetMessage(err.Error())
|
||||
|
||||
return internalErrorStatus
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
func TestFromStatusV2(t *testing.T) {
|
||||
type statusConstructor func() apistatus.Status
|
||||
type statusConstructor func() error
|
||||
|
||||
for _, testItem := range [...]struct {
|
||||
status any // Status or statusConstructor
|
||||
|
@ -19,32 +19,20 @@ func TestFromStatusV2(t *testing.T) {
|
|||
checkAsErr func(error) bool
|
||||
}{
|
||||
{
|
||||
status: errors.New("some error"),
|
||||
status: (statusConstructor)(func() error {
|
||||
return errors.New("some error")
|
||||
}),
|
||||
codeV2: 1024,
|
||||
messageV2: "some error",
|
||||
},
|
||||
{
|
||||
status: 1,
|
||||
status: (statusConstructor)(func() error {
|
||||
return nil
|
||||
}),
|
||||
codeV2: 0,
|
||||
},
|
||||
{
|
||||
status: "text",
|
||||
codeV2: 0,
|
||||
},
|
||||
{
|
||||
status: false,
|
||||
codeV2: 0,
|
||||
},
|
||||
{
|
||||
status: true,
|
||||
codeV2: 0,
|
||||
},
|
||||
{
|
||||
status: nil,
|
||||
codeV2: 0,
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
st := new(apistatus.ServerInternal)
|
||||
st.SetMessage("internal error message")
|
||||
|
||||
|
@ -58,7 +46,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
st := new(apistatus.WrongMagicNumber)
|
||||
st.WriteCorrectMagic(322)
|
||||
|
||||
|
@ -72,7 +60,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
return new(apistatus.ObjectLocked)
|
||||
}),
|
||||
codeV2: 2050,
|
||||
|
@ -83,7 +71,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
return new(apistatus.LockNonRegularObject)
|
||||
}),
|
||||
codeV2: 2051,
|
||||
|
@ -94,7 +82,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
st := new(apistatus.ObjectAccessDenied)
|
||||
st.WriteReason("any reason")
|
||||
|
||||
|
@ -108,7 +96,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
return new(apistatus.ObjectNotFound)
|
||||
}),
|
||||
codeV2: 2049,
|
||||
|
@ -119,7 +107,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
return new(apistatus.ObjectAlreadyRemoved)
|
||||
}),
|
||||
codeV2: 2052,
|
||||
|
@ -130,7 +118,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: statusConstructor(func() apistatus.Status {
|
||||
status: statusConstructor(func() error {
|
||||
return new(apistatus.ObjectOutOfRange)
|
||||
}),
|
||||
codeV2: 2053,
|
||||
|
@ -141,7 +129,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
return new(apistatus.ContainerNotFound)
|
||||
}),
|
||||
codeV2: 3072,
|
||||
|
@ -152,7 +140,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
return new(apistatus.EACLNotFound)
|
||||
}),
|
||||
codeV2: 3073,
|
||||
|
@ -163,7 +151,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
return new(apistatus.SessionTokenNotFound)
|
||||
}),
|
||||
codeV2: 4096,
|
||||
|
@ -174,7 +162,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
return new(apistatus.SessionTokenExpired)
|
||||
}),
|
||||
codeV2: 4097,
|
||||
|
@ -185,7 +173,7 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
status: (statusConstructor)(func() apistatus.Status {
|
||||
status: (statusConstructor)(func() error {
|
||||
return new(apistatus.NodeUnderMaintenance)
|
||||
}),
|
||||
codeV2: 1027,
|
||||
|
@ -196,15 +184,13 @@ func TestFromStatusV2(t *testing.T) {
|
|||
},
|
||||
},
|
||||
} {
|
||||
var st apistatus.Status
|
||||
var st error
|
||||
cons, ok := testItem.status.(statusConstructor)
|
||||
require.True(t, ok)
|
||||
|
||||
if cons, ok := testItem.status.(statusConstructor); ok {
|
||||
st = cons()
|
||||
} else {
|
||||
st = testItem.status
|
||||
}
|
||||
|
||||
stv2 := apistatus.ToStatusV2(st)
|
||||
stv2 := apistatus.ErrorToV2(st)
|
||||
|
||||
// must generate the same status.Status message
|
||||
require.EqualValues(t, testItem.codeV2, stv2.Code())
|
||||
|
@ -212,27 +198,25 @@ func TestFromStatusV2(t *testing.T) {
|
|||
require.Equal(t, testItem.messageV2, stv2.Message())
|
||||
}
|
||||
|
||||
_, ok := st.(apistatus.StatusV2)
|
||||
_, ok = st.(apistatus.StatusV2)
|
||||
if ok {
|
||||
// restore and convert again
|
||||
restored := apistatus.FromStatusV2(stv2)
|
||||
restored := apistatus.ErrorFromV2(stv2)
|
||||
|
||||
res := apistatus.ToStatusV2(restored)
|
||||
res := apistatus.ErrorToV2(restored)
|
||||
|
||||
// must generate the same status.Status message
|
||||
require.Equal(t, stv2, res)
|
||||
}
|
||||
|
||||
randomError := errors.New("garbage")
|
||||
errFromStatus := apistatus.ErrFromStatus(st)
|
||||
|
||||
for _, err := range testItem.compatibleErrs {
|
||||
require.ErrorIs(t, errFromStatus, err)
|
||||
require.ErrorIs(t, st, err)
|
||||
require.NotErrorIs(t, randomError, err)
|
||||
}
|
||||
|
||||
if testItem.checkAsErr != nil {
|
||||
require.True(t, testItem.checkAsErr(errFromStatus))
|
||||
require.True(t, testItem.checkAsErr(st))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
sessionv2 "github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/accounting"
|
||||
sdkClient "github.com/nspcc-dev/neofs-sdk-go/client"
|
||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/container"
|
||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
|
||||
|
@ -27,7 +26,7 @@ type mockClient struct {
|
|||
errorOnCreateSession bool
|
||||
errorOnEndpointInfo bool
|
||||
errorOnNetworkInfo bool
|
||||
stOnGetObject apistatus.Status
|
||||
errOnGetObject error
|
||||
}
|
||||
|
||||
func newMockClient(addr string, signer neofscrypto.Signer) *mockClient {
|
||||
|
@ -60,8 +59,8 @@ func (m *mockClient) errOnDial() {
|
|||
m.errOnNetworkInfo()
|
||||
}
|
||||
|
||||
func (m *mockClient) statusOnGetObject(st apistatus.Status) {
|
||||
m.stOnGetObject = st
|
||||
func (m *mockClient) statusOnGetObject(err error) {
|
||||
m.errOnGetObject = err
|
||||
}
|
||||
|
||||
func newToken(signer neofscrypto.Signer) *session.Object {
|
||||
|
@ -139,13 +138,12 @@ func (m *mockClient) objectDelete(context.Context, PrmObjectDelete) error {
|
|||
func (m *mockClient) objectGet(context.Context, PrmObjectGet) (ResGetObject, error) {
|
||||
var res ResGetObject
|
||||
|
||||
if m.stOnGetObject == nil {
|
||||
if m.errOnGetObject == nil {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
err := apistatus.ErrFromStatus(m.stOnGetObject)
|
||||
m.updateErrorRate(err)
|
||||
return res, err
|
||||
m.updateErrorRate(m.errOnGetObject)
|
||||
return res, m.errOnGetObject
|
||||
}
|
||||
|
||||
func (m *mockClient) objectHead(context.Context, PrmObjectHead) (object.Object, error) {
|
||||
|
|
Loading…
Reference in a new issue