*: Remove statusRes as unused

Fixes #405

Signed-off-by: Evgenii Baidakov <evgenii@nspcc.io>
This commit is contained in:
Evgenii Baidakov 2023-05-17 16:32:42 +04:00
parent e0afe0807c
commit e377b3b4f6
No known key found for this signature in database
GPG key ID: 8733EE3D72CDB4DE
15 changed files with 116 additions and 300 deletions

View file

@ -28,8 +28,6 @@ func (x *PrmBalanceGet) SetAccount(id user.ID) {
// ResBalanceGet groups resulting values of BalanceGet operation. // ResBalanceGet groups resulting values of BalanceGet operation.
type ResBalanceGet struct { type ResBalanceGet struct {
statusRes
amount accounting.Decimal amount accounting.Decimal
} }

View file

@ -11,18 +11,6 @@ import (
"github.com/nspcc-dev/neofs-sdk-go/version" "github.com/nspcc-dev/neofs-sdk-go/version"
) )
// structure is embedded to all resulting types in order to inherit status-related methods.
type statusRes struct {
st apistatus.Status
}
// Status returns server's status return.
//
// Use apistatus package functionality to handle the status.
func (x statusRes) Status() apistatus.Status {
return x.st
}
// groups meta parameters shared between all Client operations. // groups meta parameters shared between all Client operations.
type prmCommonMeta struct { type prmCommonMeta struct {
// NeoFS request X-Headers // NeoFS request X-Headers

View file

@ -60,8 +60,6 @@ func (x *PrmContainerPut) WithinSession(s session.Container) {
// ResContainerPut groups resulting values of ContainerPut operation. // ResContainerPut groups resulting values of ContainerPut operation.
type ResContainerPut struct { type ResContainerPut struct {
statusRes
id cid.ID id cid.ID
} }
@ -193,8 +191,6 @@ func (x *PrmContainerGet) SetContainer(id cid.ID) {
// ResContainerGet groups resulting values of ContainerGet operation. // ResContainerGet groups resulting values of ContainerGet operation.
type ResContainerGet struct { type ResContainerGet struct {
statusRes
cnr container.Container cnr container.Container
} }
@ -285,8 +281,6 @@ func (x *PrmContainerList) SetAccount(id user.ID) {
// ResContainerList groups resulting values of ContainerList operation. // ResContainerList groups resulting values of ContainerList operation.
type ResContainerList struct { type ResContainerList struct {
statusRes
ids []cid.ID ids []cid.ID
} }
@ -398,11 +392,6 @@ func (x *PrmContainerDelete) WithinSession(tok session.Container) {
x.tokSet = true x.tokSet = true
} }
// ResContainerDelete groups resulting values of ContainerDelete operation.
type ResContainerDelete struct {
statusRes
}
// ContainerDelete sends request to remove the NeoFS container. // ContainerDelete sends request to remove the NeoFS container.
// //
// Any errors (local or remote, including returned status codes) are returned as Go errors, // Any errors (local or remote, including returned status codes) are returned as Go errors,
@ -416,9 +405,8 @@ type ResContainerDelete struct {
// Immediately panics if parameters are set incorrectly (see PrmContainerDelete docs). // Immediately panics if parameters are set incorrectly (see PrmContainerDelete docs).
// Context is required and must not be nil. It is used for network communication. // Context is required and must not be nil. It is used for network communication.
// //
// Exactly one return value is non-nil. Server status return is returned in ResContainerDelete.
// Reflects all internal errors in second return value (transport problems, response processing, etc.). // Reflects all internal errors in second return value (transport problems, response processing, etc.).
func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*ResContainerDelete, error) { func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) error {
// check parameters // check parameters
switch { switch {
case ctx == nil: case ctx == nil:
@ -443,7 +431,7 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*
err := sig.Calculate(signer, data) err := sig.Calculate(signer, data)
if err != nil { if err != nil {
return nil, fmt.Errorf("calculate signature: %w", err) return fmt.Errorf("calculate signature: %w", err)
} }
var sigv2 refs.Signature var sigv2 refs.Signature
@ -475,8 +463,7 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*
// init call context // init call context
var ( var (
cc contextCall cc contextCall
res ResContainerDelete
) )
c.initCallContext(&cc) c.initCallContext(&cc)
@ -487,10 +474,10 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*
// process call // process call
if !cc.processCall() { if !cc.processCall() {
return nil, cc.err return cc.err
} }
return &res, nil return nil
} }
// PrmContainerEACL groups parameters of ContainerEACL operation. // PrmContainerEACL groups parameters of ContainerEACL operation.
@ -510,8 +497,6 @@ func (x *PrmContainerEACL) SetContainer(id cid.ID) {
// ResContainerEACL groups resulting values of ContainerEACL operation. // ResContainerEACL groups resulting values of ContainerEACL operation.
type ResContainerEACL struct { type ResContainerEACL struct {
statusRes
table eacl.Table table eacl.Table
} }
@ -624,11 +609,6 @@ func (x *PrmContainerSetEACL) WithinSession(s session.Container) {
x.sessionSet = true x.sessionSet = true
} }
// ResContainerSetEACL groups resulting values of ContainerSetEACL operation.
type ResContainerSetEACL struct {
statusRes
}
// ContainerSetEACL sends request to update eACL table of the NeoFS container. // ContainerSetEACL sends request to update eACL table of the NeoFS container.
// //
// Any errors (local or remote, including returned status codes) are returned as Go errors, // Any errors (local or remote, including returned status codes) are returned as Go errors,
@ -641,7 +621,7 @@ type ResContainerSetEACL struct {
// //
// Immediately panics if parameters are set incorrectly (see PrmContainerSetEACL docs). // Immediately panics if parameters are set incorrectly (see PrmContainerSetEACL docs).
// Context is required and must not be nil. It is used for network communication. // Context is required and must not be nil. It is used for network communication.
func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL) (*ResContainerSetEACL, error) { func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL) error {
// check parameters // check parameters
switch { switch {
case ctx == nil: case ctx == nil:
@ -666,7 +646,7 @@ func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL)
err := sig.Calculate(signer, eaclV2.StableMarshal(nil)) err := sig.Calculate(signer, eaclV2.StableMarshal(nil))
if err != nil { if err != nil {
return nil, fmt.Errorf("calculate signature: %w", err) return fmt.Errorf("calculate signature: %w", err)
} }
var sigv2 refs.Signature var sigv2 refs.Signature
@ -698,8 +678,7 @@ func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL)
// init call context // init call context
var ( var (
cc contextCall cc contextCall
res ResContainerSetEACL
) )
c.initCallContext(&cc) c.initCallContext(&cc)
@ -710,10 +689,10 @@ func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL)
// process call // process call
if !cc.processCall() { if !cc.processCall() {
return nil, cc.err return cc.err
} }
return &res, nil return nil
} }
// PrmAnnounceSpace groups parameters of ContainerAnnounceUsedSpace operation. // PrmAnnounceSpace groups parameters of ContainerAnnounceUsedSpace operation.
@ -731,11 +710,6 @@ func (x *PrmAnnounceSpace) SetValues(vs []container.SizeEstimation) {
x.announcements = vs x.announcements = vs
} }
// ResAnnounceSpace groups resulting values of ContainerAnnounceUsedSpace operation.
type ResAnnounceSpace struct {
statusRes
}
// ContainerAnnounceUsedSpace sends request to announce volume of the space used for the container objects. // ContainerAnnounceUsedSpace sends request to announce volume of the space used for the container objects.
// //
// Any errors (local or remote, including returned status codes) are returned as Go errors, // Any errors (local or remote, including returned status codes) are returned as Go errors,
@ -748,7 +722,7 @@ type ResAnnounceSpace struct {
// //
// Immediately panics if parameters are set incorrectly (see PrmAnnounceSpace docs). // Immediately panics if parameters are set incorrectly (see PrmAnnounceSpace docs).
// Context is required and must not be nil. It is used for network communication. // Context is required and must not be nil. It is used for network communication.
func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, prm PrmAnnounceSpace) (*ResAnnounceSpace, error) { func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, prm PrmAnnounceSpace) error {
// check parameters // check parameters
switch { switch {
case ctx == nil: case ctx == nil:
@ -775,8 +749,7 @@ func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, prm PrmAnnounce
// init call context // init call context
var ( var (
cc contextCall cc contextCall
res ResAnnounceSpace
) )
c.initCallContext(&cc) c.initCallContext(&cc)
@ -788,10 +761,10 @@ func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, prm PrmAnnounce
// process call // process call
if !cc.processCall() { if !cc.processCall() {
return nil, cc.err return cc.err
} }
return &res, nil return nil
} }
// SyncContainerWithNetwork requests network configuration using passed client // SyncContainerWithNetwork requests network configuration using passed client

View file

@ -8,7 +8,6 @@ import (
rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc" rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc"
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
v2session "github.com/nspcc-dev/neofs-api-go/v2/session" v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
"github.com/nspcc-dev/neofs-sdk-go/netmap" "github.com/nspcc-dev/neofs-sdk-go/netmap"
"github.com/nspcc-dev/neofs-sdk-go/version" "github.com/nspcc-dev/neofs-sdk-go/version"
) )
@ -20,8 +19,6 @@ type PrmEndpointInfo struct {
// ResEndpointInfo group resulting values of EndpointInfo operation. // ResEndpointInfo group resulting values of EndpointInfo operation.
type ResEndpointInfo struct { type ResEndpointInfo struct {
statusRes
version version.Version version version.Version
ni netmap.NodeInfo ni netmap.NodeInfo
@ -120,8 +117,6 @@ type PrmNetworkInfo struct {
// ResNetworkInfo groups resulting values of NetworkInfo operation. // ResNetworkInfo groups resulting values of NetworkInfo operation.
type ResNetworkInfo struct { type ResNetworkInfo struct {
statusRes
info netmap.NetworkInfo info netmap.NetworkInfo
} }
@ -194,8 +189,6 @@ type PrmNetMapSnapshot struct {
// ResNetMapSnapshot groups resulting values of NetMapSnapshot operation. // ResNetMapSnapshot groups resulting values of NetMapSnapshot operation.
type ResNetMapSnapshot struct { type ResNetMapSnapshot struct {
statusRes
netMap netmap.NetMap netMap netmap.NetMap
} }
@ -241,15 +234,11 @@ func (c *Client) NetMapSnapshot(ctx context.Context, _ PrmNetMapSnapshot) (*ResN
} }
var res ResNetMapSnapshot var res ResNetMapSnapshot
res.st, err = c.processResponse(resp) _, err = c.processResponse(resp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !apistatus.IsSuccessful(res.st) {
return &res, nil
}
const fieldNetMap = "network map" const fieldNetMap = "network map"
netMapV2 := resp.GetBody().NetMap() netMapV2 := resp.GetBody().NetMap()

View file

@ -145,6 +145,5 @@ func TestClient_NetMapSnapshot(t *testing.T) {
res, err = c.NetMapSnapshot(ctx, prm) res, err = c.NetMapSnapshot(ctx, prm)
require.NoError(t, err) require.NoError(t, err)
require.True(t, apistatus.IsSuccessful(res.Status()))
require.Equal(t, netMap, res.NetMap()) require.Equal(t, netMap, res.NetMap())
} }

View file

@ -11,7 +11,6 @@ import (
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
v2session "github.com/nspcc-dev/neofs-api-go/v2/session" v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-sdk-go/bearer" "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" cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto" neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id" oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
@ -95,8 +94,6 @@ func (x *PrmObjectDelete) WithXHeaders(hs ...string) {
// ResObjectDelete groups resulting values of ObjectDelete operation. // ResObjectDelete groups resulting values of ObjectDelete operation.
type ResObjectDelete struct { type ResObjectDelete struct {
statusRes
tomb oid.ID tomb oid.ID
} }
@ -160,15 +157,11 @@ func (c *Client) ObjectDelete(ctx context.Context, prm PrmObjectDelete) (*ResObj
} }
var res ResObjectDelete var res ResObjectDelete
res.st, err = c.processResponse(resp) _, err = c.processResponse(resp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !apistatus.IsSuccessful(res.st) {
return &res, nil
}
const fieldTombstone = "tombstone" const fieldTombstone = "tombstone"
idTombV2 := resp.GetBody().GetTombstone().GetObjectID() idTombV2 := resp.GetBody().GetTombstone().GetObjectID()

View file

@ -13,7 +13,6 @@ import (
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
v2session "github.com/nspcc-dev/neofs-api-go/v2/session" v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-sdk-go/bearer" "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" cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto" neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
"github.com/nspcc-dev/neofs-sdk-go/object" "github.com/nspcc-dev/neofs-sdk-go/object"
@ -100,11 +99,6 @@ type PrmObjectGet struct {
signer neofscrypto.Signer signer neofscrypto.Signer
} }
// ResObjectGet groups the final result values of ObjectGetInit operation.
type ResObjectGet struct {
statusRes
}
// ObjectReader is designed to read one object from NeoFS system. // ObjectReader is designed to read one object from NeoFS system.
// //
// Must be initialized using Client.ObjectGetInit, any other // Must be initialized using Client.ObjectGetInit, any other
@ -117,7 +111,6 @@ type ObjectReader struct {
Read(resp *v2object.GetResponse) error Read(resp *v2object.GetResponse) error
} }
res ResObjectGet
err error err error
tailPayload []byte tailPayload []byte
@ -140,8 +133,8 @@ func (x *ObjectReader) ReadHeader(dst *object.Object) bool {
return false return false
} }
x.res.st, x.err = x.client.processResponse(&resp) _, x.err = x.client.processResponse(&resp)
if x.err != nil || !apistatus.IsSuccessful(x.res.st) { if x.err != nil {
return false return false
} }
@ -193,8 +186,8 @@ func (x *ObjectReader) readChunk(buf []byte) (int, bool) {
return read, false return read, false
} }
x.res.st, x.err = x.client.processResponse(&resp) _, x.err = x.client.processResponse(&resp)
if x.err != nil || !apistatus.IsSuccessful(x.res.st) { if x.err != nil {
return read, false return read, false
} }
@ -233,28 +226,27 @@ func (x *ObjectReader) ReadChunk(buf []byte) (int, bool) {
return x.readChunk(buf) return x.readChunk(buf)
} }
func (x *ObjectReader) close(ignoreEOF bool) (*ResObjectGet, error) { func (x *ObjectReader) close(ignoreEOF bool) error {
defer x.cancelCtxStream() defer x.cancelCtxStream()
if x.err != nil { if x.err != nil {
if !errors.Is(x.err, io.EOF) { if !errors.Is(x.err, io.EOF) {
return nil, x.err return x.err
} else if !ignoreEOF { } else if !ignoreEOF {
if x.remainingPayloadLen > 0 { if x.remainingPayloadLen > 0 {
return nil, io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
return nil, io.EOF return io.EOF
} }
} }
return &x.res, nil return nil
} }
// Close ends reading the object and returns the result of the operation // Close ends reading the object and returns the result of the operation
// along with the final results. Must be called after using the ObjectReader. // along with the final results. Must be called after using the ObjectReader.
// //
// Exactly one return value is non-nil. By default, server status is returned in res structure.
// Any client's internal or transport errors are returned as Go built-in error. // Any client's internal or transport errors are returned as Go built-in error.
// If Client is tuned to resolve NeoFS API statuses, then NeoFS failures // If Client is tuned to resolve NeoFS API statuses, then NeoFS failures
// codes are returned as error. // codes are returned as error.
@ -267,7 +259,7 @@ func (x *ObjectReader) close(ignoreEOF bool) (*ResObjectGet, error) {
// - [apistatus.ErrObjectAccessDenied]; // - [apistatus.ErrObjectAccessDenied];
// - [apistatus.ErrObjectAlreadyRemoved]; // - [apistatus.ErrObjectAlreadyRemoved];
// - [apistatus.ErrSessionTokenExpired]. // - [apistatus.ErrSessionTokenExpired].
func (x *ObjectReader) Close() (*ResObjectGet, error) { func (x *ObjectReader) Close() error {
return x.close(true) return x.close(true)
} }
@ -278,12 +270,11 @@ func (x *ObjectReader) Read(p []byte) (int, error) {
x.remainingPayloadLen -= n x.remainingPayloadLen -= n
if !ok { if !ok {
res, err := x.close(false) if err := x.close(false); err != nil {
if err != nil {
return n, err return n, err
} }
return n, apistatus.ErrFromStatus(res.Status()) return n, x.err
} }
if x.remainingPayloadLen < 0 { if x.remainingPayloadLen < 0 {
@ -364,8 +355,6 @@ func (x *PrmObjectHead) UseSigner(signer neofscrypto.Signer) {
// ResObjectHead groups resulting values of ObjectHead operation. // ResObjectHead groups resulting values of ObjectHead operation.
type ResObjectHead struct { type ResObjectHead struct {
statusRes
// requested object (response doesn't carry the ID) // requested object (response doesn't carry the ID)
idObj oid.ID idObj oid.ID
@ -444,15 +433,11 @@ func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectH
} }
var res ResObjectHead var res ResObjectHead
res.st, err = c.processResponse(resp) _, err = c.processResponse(resp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !apistatus.IsSuccessful(res.st) {
return &res, nil
}
_ = res.idObj.ReadFromV2(*prm.addr.GetObjectID()) _ = res.idObj.ReadFromV2(*prm.addr.GetObjectID())
switch v := resp.GetBody().GetHeaderPart().(type) { switch v := resp.GetBody().GetHeaderPart().(type) {
@ -500,11 +485,6 @@ func (x *PrmObjectRange) UseSigner(signer neofscrypto.Signer) {
x.signer = signer x.signer = signer
} }
// ResObjectRange groups the final result values of ObjectRange operation.
type ResObjectRange struct {
statusRes
}
// ObjectRangeReader is designed to read payload range of one object // ObjectRangeReader is designed to read payload range of one object
// from NeoFS system. // from NeoFS system.
// //
@ -515,7 +495,6 @@ type ObjectRangeReader struct {
client *Client client *Client
res ResObjectRange
err error err error
stream interface { stream interface {
@ -550,8 +529,8 @@ func (x *ObjectRangeReader) readChunk(buf []byte) (int, bool) {
return read, false return read, false
} }
x.res.st, x.err = x.client.processResponse(&resp) _, x.err = x.client.processResponse(&resp)
if x.err != nil || !apistatus.IsSuccessful(x.res.st) { if x.err != nil {
return read, false return read, false
} }
@ -594,28 +573,27 @@ func (x *ObjectRangeReader) ReadChunk(buf []byte) (int, bool) {
return x.readChunk(buf) return x.readChunk(buf)
} }
func (x *ObjectRangeReader) close(ignoreEOF bool) (*ResObjectRange, error) { func (x *ObjectRangeReader) close(ignoreEOF bool) error {
defer x.cancelCtxStream() defer x.cancelCtxStream()
if x.err != nil { if x.err != nil {
if !errors.Is(x.err, io.EOF) { if !errors.Is(x.err, io.EOF) {
return nil, x.err return x.err
} else if !ignoreEOF { } else if !ignoreEOF {
if x.remainingPayloadLen > 0 { if x.remainingPayloadLen > 0 {
return nil, io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
return nil, io.EOF return io.EOF
} }
} }
return &x.res, nil return nil
} }
// Close ends reading the payload range and returns the result of the operation // Close ends reading the payload range and returns the result of the operation
// along with the final results. Must be called after using the ObjectRangeReader. // along with the final results. Must be called after using the ObjectRangeReader.
// //
// Exactly one return value is non-nil. By default, server status is returned in res structure.
// Any client's internal or transport errors are returned as Go built-in error. // Any client's internal or transport errors are returned as Go built-in error.
// If Client is tuned to resolve NeoFS API statuses, then NeoFS failures // If Client is tuned to resolve NeoFS API statuses, then NeoFS failures
// codes are returned as error. // codes are returned as error.
@ -629,7 +607,7 @@ func (x *ObjectRangeReader) close(ignoreEOF bool) (*ResObjectRange, error) {
// - [apistatus.ErrObjectAlreadyRemoved]; // - [apistatus.ErrObjectAlreadyRemoved];
// - [apistatus.ErrObjectOutOfRange]; // - [apistatus.ErrObjectOutOfRange];
// - [apistatus.ErrSessionTokenExpired]. // - [apistatus.ErrSessionTokenExpired].
func (x *ObjectRangeReader) Close() (*ResObjectRange, error) { func (x *ObjectRangeReader) Close() error {
return x.close(true) return x.close(true)
} }
@ -640,12 +618,12 @@ func (x *ObjectRangeReader) Read(p []byte) (int, error) {
x.remainingPayloadLen -= n x.remainingPayloadLen -= n
if !ok { if !ok {
res, err := x.close(false) err := x.close(false)
if err != nil { if err != nil {
return n, err return n, err
} }
return n, apistatus.ErrFromStatus(res.Status()) return n, x.err
} }
if x.remainingPayloadLen < 0 { if x.remainingPayloadLen < 0 {

View file

@ -11,7 +11,6 @@ import (
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
v2session "github.com/nspcc-dev/neofs-api-go/v2/session" v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-sdk-go/bearer" "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" cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto" neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id" oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
@ -135,8 +134,6 @@ func (x *PrmObjectHash) WithXHeaders(hs ...string) {
// ResObjectHash groups resulting values of ObjectHash operation. // ResObjectHash groups resulting values of ObjectHash operation.
type ResObjectHash struct { type ResObjectHash struct {
statusRes
checksums [][]byte checksums [][]byte
} }
@ -196,15 +193,11 @@ func (c *Client) ObjectHash(ctx context.Context, prm PrmObjectHash) (*ResObjectH
} }
var res ResObjectHash var res ResObjectHash
res.st, err = c.processResponse(resp) _, err = c.processResponse(resp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !apistatus.IsSuccessful(res.st) {
return &res, nil
}
res.checksums = resp.GetBody().GetHashList() res.checksums = resp.GetBody().GetHashList()
if len(res.checksums) == 0 { if len(res.checksums) == 0 {
return nil, newErrMissingResponseField("hash list") return nil, newErrMissingResponseField("hash list")

View file

@ -36,8 +36,6 @@ func (x *PrmObjectPutInit) SetCopiesNumber(copiesNumber uint32) {
// ResObjectPut groups the final result values of ObjectPutInit operation. // ResObjectPut groups the final result values of ObjectPutInit operation.
type ResObjectPut struct { type ResObjectPut struct {
statusRes
obj oid.ID obj oid.ID
} }
@ -208,15 +206,11 @@ func (x *ObjectWriter) Close() (*ResObjectPut, error) {
return nil, x.err return nil, x.err
} }
x.res.st, x.err = x.client.processResponse(&x.respV2) _, x.err = x.client.processResponse(&x.respV2)
if x.err != nil { if x.err != nil {
return nil, x.err return nil, x.err
} }
if !apistatus.IsSuccessful(x.res.st) {
return &x.res, nil
}
const fieldID = "ID" const fieldID = "ID"
idV2 := x.respV2.GetBody().GetObjectID() idV2 := x.respV2.GetBody().GetObjectID()
@ -291,7 +285,7 @@ func (x *objectWriter) InitDataStream(header object.Object) (io.Writer, error) {
return nil, err return nil, err
} }
return nil, apistatus.ErrFromStatus(res.Status()) return nil, apistatus.ErrFromStatus(res)
} }
type payloadWriter struct { type payloadWriter struct {
@ -312,7 +306,7 @@ func (x *payloadWriter) Close() error {
return err return err
} }
return apistatus.ErrFromStatus(res.Status()) return apistatus.ErrFromStatus(res)
} }
// CreateObject creates new NeoFS object with given payload data and stores it // CreateObject creates new NeoFS object with given payload data and stores it

View file

@ -13,7 +13,6 @@ import (
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
v2session "github.com/nspcc-dev/neofs-api-go/v2/session" v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-sdk-go/bearer" "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" cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto" neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
"github.com/nspcc-dev/neofs-sdk-go/object" "github.com/nspcc-dev/neofs-sdk-go/object"
@ -88,11 +87,6 @@ func (x *PrmObjectSearch) SetFilters(filters object.SearchFilters) {
x.filters = filters x.filters = filters
} }
// ResObjectSearch groups the final result values of ObjectSearch operation.
type ResObjectSearch struct {
statusRes
}
// ObjectListReader is designed to read list of object identifiers from NeoFS system. // ObjectListReader is designed to read list of object identifiers from NeoFS system.
// //
// Must be initialized using Client.ObjectSearch, any other usage is unsafe. // Must be initialized using Client.ObjectSearch, any other usage is unsafe.
@ -100,7 +94,6 @@ type ObjectListReader struct {
client *Client client *Client
cancelCtxStream context.CancelFunc cancelCtxStream context.CancelFunc
err error err error
res ResObjectSearch
stream interface { stream interface {
Read(resp *v2object.SearchResponse) error Read(resp *v2object.SearchResponse) error
} }
@ -132,8 +125,8 @@ func (x *ObjectListReader) Read(buf []oid.ID) (int, bool) {
return read, false return read, false
} }
x.res.st, x.err = x.client.processResponse(&resp) _, x.err = x.client.processResponse(&resp)
if x.err != nil || !apistatus.IsSuccessful(x.res.st) { if x.err != nil {
return read, false return read, false
} }
@ -176,11 +169,7 @@ func (x *ObjectListReader) Iterate(f func(oid.ID) bool) error {
// so false means nothing was read. // so false means nothing was read.
_, ok := x.Read(buf) _, ok := x.Read(buf)
if !ok { if !ok {
res, err := x.Close() return x.Close()
if err != nil {
return err
}
return apistatus.ErrFromStatus(res.Status())
} }
if f(buf[0]) { if f(buf[0]) {
return nil return nil
@ -191,7 +180,6 @@ func (x *ObjectListReader) Iterate(f func(oid.ID) bool) error {
// Close ends reading list of the matched objects and returns the result of the operation // Close ends reading list of the matched objects and returns the result of the operation
// along with the final results. Must be called after using the ObjectListReader. // along with the final results. Must be called after using the ObjectListReader.
// //
// Exactly one return value is non-nil. By default, server status is returned in res structure.
// Any client's internal or transport errors are returned as Go built-in error. // Any client's internal or transport errors are returned as Go built-in error.
// If Client is tuned to resolve NeoFS API statuses, then NeoFS failures // If Client is tuned to resolve NeoFS API statuses, then NeoFS failures
// codes are returned as error. // codes are returned as error.
@ -201,14 +189,14 @@ func (x *ObjectListReader) Iterate(f func(oid.ID) bool) error {
// - [apistatus.ErrContainerNotFound]; // - [apistatus.ErrContainerNotFound];
// - [apistatus.ErrObjectAccessDenied]; // - [apistatus.ErrObjectAccessDenied];
// - [apistatus.ErrSessionTokenExpired]. // - [apistatus.ErrSessionTokenExpired].
func (x *ObjectListReader) Close() (*ResObjectSearch, error) { func (x *ObjectListReader) Close() error {
defer x.cancelCtxStream() defer x.cancelCtxStream()
if x.err != nil && !errors.Is(x.err, io.EOF) { if x.err != nil && !errors.Is(x.err, io.EOF) {
return nil, x.err return x.err
} }
return &x.res, nil return nil
} }
// ObjectSearchInit initiates object selection through a remote server using NeoFS API protocol. // ObjectSearchInit initiates object selection through a remote server using NeoFS API protocol.

View file

@ -32,11 +32,6 @@ func (x *PrmAnnounceLocalTrust) SetValues(trusts []reputation.Trust) {
x.trusts = trusts x.trusts = trusts
} }
// ResAnnounceLocalTrust groups results of AnnounceLocalTrust operation.
type ResAnnounceLocalTrust struct {
statusRes
}
// AnnounceLocalTrust sends client's trust values to the NeoFS network participants. // AnnounceLocalTrust sends client's trust values to the NeoFS network participants.
// //
// Any errors (local or remote, including returned status codes) are returned as Go errors, // Any errors (local or remote, including returned status codes) are returned as Go errors,
@ -44,7 +39,7 @@ type ResAnnounceLocalTrust struct {
// //
// Immediately panics if parameters are set incorrectly (see PrmAnnounceLocalTrust docs). // Immediately panics if parameters are set incorrectly (see PrmAnnounceLocalTrust docs).
// Context is required and must not be nil. It is used for network communication. // Context is required and must not be nil. It is used for network communication.
func (c *Client) AnnounceLocalTrust(ctx context.Context, prm PrmAnnounceLocalTrust) (*ResAnnounceLocalTrust, error) { func (c *Client) AnnounceLocalTrust(ctx context.Context, prm PrmAnnounceLocalTrust) error {
// check parameters // check parameters
switch { switch {
case ctx == nil: case ctx == nil:
@ -75,8 +70,7 @@ func (c *Client) AnnounceLocalTrust(ctx context.Context, prm PrmAnnounceLocalTru
// init call context // init call context
var ( var (
cc contextCall cc contextCall
res ResAnnounceLocalTrust
) )
c.initCallContext(&cc) c.initCallContext(&cc)
@ -88,10 +82,10 @@ func (c *Client) AnnounceLocalTrust(ctx context.Context, prm PrmAnnounceLocalTru
// process call // process call
if !cc.processCall() { if !cc.processCall() {
return nil, cc.err return cc.err
} }
return &res, nil return nil
} }
// PrmAnnounceIntermediateTrust groups parameters of AnnounceIntermediateTrust operation. // PrmAnnounceIntermediateTrust groups parameters of AnnounceIntermediateTrust operation.
@ -125,11 +119,6 @@ func (x *PrmAnnounceIntermediateTrust) SetCurrentValue(trust reputation.PeerToPe
x.trustSet = true x.trustSet = true
} }
// ResAnnounceIntermediateTrust groups results of AnnounceIntermediateTrust operation.
type ResAnnounceIntermediateTrust struct {
statusRes
}
// AnnounceIntermediateTrust sends global trust values calculated for the specified NeoFS network participants // AnnounceIntermediateTrust sends global trust values calculated for the specified NeoFS network participants
// at some stage of client's calculation algorithm. // at some stage of client's calculation algorithm.
// //
@ -138,7 +127,7 @@ type ResAnnounceIntermediateTrust struct {
// //
// Immediately panics if parameters are set incorrectly (see PrmAnnounceIntermediateTrust docs). // Immediately panics if parameters are set incorrectly (see PrmAnnounceIntermediateTrust docs).
// Context is required and must not be nil. It is used for network communication. // Context is required and must not be nil. It is used for network communication.
func (c *Client) AnnounceIntermediateTrust(ctx context.Context, prm PrmAnnounceIntermediateTrust) (*ResAnnounceIntermediateTrust, error) { func (c *Client) AnnounceIntermediateTrust(ctx context.Context, prm PrmAnnounceIntermediateTrust) error {
// check parameters // check parameters
switch { switch {
case ctx == nil: case ctx == nil:
@ -166,8 +155,7 @@ func (c *Client) AnnounceIntermediateTrust(ctx context.Context, prm PrmAnnounceI
// init call context // init call context
var ( var (
cc contextCall cc contextCall
res ResAnnounceIntermediateTrust
) )
c.initCallContext(&cc) c.initCallContext(&cc)
@ -179,8 +167,8 @@ func (c *Client) AnnounceIntermediateTrust(ctx context.Context, prm PrmAnnounceI
// process call // process call
if !cc.processCall() { if !cc.processCall() {
return nil, cc.err return cc.err
} }
return &res, nil return nil
} }

View file

@ -32,8 +32,6 @@ func (x *PrmSessionCreate) UseSigner(signer neofscrypto.Signer) {
// ResSessionCreate groups resulting values of SessionCreate operation. // ResSessionCreate groups resulting values of SessionCreate operation.
type ResSessionCreate struct { type ResSessionCreate struct {
statusRes
id []byte id []byte
sessionKey []byte sessionKey []byte

View file

@ -107,7 +107,7 @@ func (m *mockClient) endpointInfo(context.Context, prmEndpointInfo) (netmap.Node
var ni netmap.NodeInfo var ni netmap.NodeInfo
if m.errorOnEndpointInfo { if m.errorOnEndpointInfo {
return ni, m.handleError(nil, errors.New("error")) return ni, m.handleError(errors.New("error"))
} }
ni.SetNetworkEndpoints(m.addr) ni.SetNetworkEndpoints(m.addr)
@ -118,7 +118,7 @@ func (m *mockClient) networkInfo(context.Context, prmNetworkInfo) (netmap.Networ
var ni netmap.NetworkInfo var ni netmap.NetworkInfo
if m.errorOnNetworkInfo { if m.errorOnNetworkInfo {
return ni, m.handleError(nil, errors.New("error")) return ni, m.handleError(errors.New("error"))
} }
return ni, nil return ni, nil
@ -139,8 +139,8 @@ func (m *mockClient) objectGet(context.Context, PrmObjectGet) (ResGetObject, err
return res, nil return res, nil
} }
status := apistatus.ErrFromStatus(m.stOnGetObject) err := apistatus.ErrFromStatus(m.stOnGetObject)
return res, m.handleError(status, nil) return res, m.handleError(err)
} }
func (m *mockClient) objectHead(context.Context, PrmObjectHead) (object.Object, error) { func (m *mockClient) objectHead(context.Context, PrmObjectHead) (object.Object, error) {
@ -157,7 +157,7 @@ func (m *mockClient) objectSearch(context.Context, PrmObjectSearch) (ResObjectSe
func (m *mockClient) sessionCreate(context.Context, prmCreateSession) (resCreateSession, error) { func (m *mockClient) sessionCreate(context.Context, prmCreateSession) (resCreateSession, error) {
if m.errorOnCreateSession { if m.errorOnCreateSession {
return resCreateSession{}, m.handleError(nil, errors.New("error")) return resCreateSession{}, m.handleError(errors.New("error"))
} }
tok := newToken(m.signer) tok := newToken(m.signer)

View file

@ -374,11 +374,7 @@ func (c *clientWrapper) balanceGet(ctx context.Context, prm PrmBalanceGet) (acco
start := time.Now() start := time.Now()
res, err := cl.BalanceGet(ctx, cliPrm) res, err := cl.BalanceGet(ctx, cliPrm)
c.incRequests(time.Since(start), methodBalanceGet) c.incRequests(time.Since(start), methodBalanceGet)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return accounting.Decimal{}, fmt.Errorf("balance get on client: %w", err) return accounting.Decimal{}, fmt.Errorf("balance get on client: %w", err)
} }
@ -396,11 +392,7 @@ func (c *clientWrapper) containerPut(ctx context.Context, prm PrmContainerPut) (
start := time.Now() start := time.Now()
res, err := cl.ContainerPut(ctx, prm.prmClient) res, err := cl.ContainerPut(ctx, prm.prmClient)
c.incRequests(time.Since(start), methodContainerPut) c.incRequests(time.Since(start), methodContainerPut)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return cid.ID{}, fmt.Errorf("container put on client: %w", err) return cid.ID{}, fmt.Errorf("container put on client: %w", err)
} }
@ -411,7 +403,7 @@ func (c *clientWrapper) containerPut(ctx context.Context, prm PrmContainerPut) (
idCnr := res.ID() idCnr := res.ID()
err = waitForContainerPresence(ctx, c, idCnr, &prm.waitParams) err = waitForContainerPresence(ctx, c, idCnr, &prm.waitParams)
if err = c.handleError(nil, err); err != nil { if err = c.handleError(err); err != nil {
return cid.ID{}, fmt.Errorf("wait container presence on client: %w", err) return cid.ID{}, fmt.Errorf("wait container presence on client: %w", err)
} }
@ -431,11 +423,7 @@ func (c *clientWrapper) containerGet(ctx context.Context, prm PrmContainerGet) (
start := time.Now() start := time.Now()
res, err := cl.ContainerGet(ctx, cliPrm) res, err := cl.ContainerGet(ctx, cliPrm)
c.incRequests(time.Since(start), methodContainerGet) c.incRequests(time.Since(start), methodContainerGet)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return container.Container{}, fmt.Errorf("container get on client: %w", err) return container.Container{}, fmt.Errorf("container get on client: %w", err)
} }
@ -455,11 +443,7 @@ func (c *clientWrapper) containerList(ctx context.Context, prm PrmContainerList)
start := time.Now() start := time.Now()
res, err := cl.ContainerList(ctx, cliPrm) res, err := cl.ContainerList(ctx, cliPrm)
c.incRequests(time.Since(start), methodContainerList) c.incRequests(time.Since(start), methodContainerList)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return nil, fmt.Errorf("container list on client: %w", err) return nil, fmt.Errorf("container list on client: %w", err)
} }
return res.Containers(), nil return res.Containers(), nil
@ -480,13 +464,9 @@ func (c *clientWrapper) containerDelete(ctx context.Context, prm PrmContainerDel
} }
start := time.Now() start := time.Now()
res, err := cl.ContainerDelete(ctx, cliPrm) err = cl.ContainerDelete(ctx, cliPrm)
c.incRequests(time.Since(start), methodContainerDelete) c.incRequests(time.Since(start), methodContainerDelete)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return fmt.Errorf("container delete on client: %w", err) return fmt.Errorf("container delete on client: %w", err)
} }
@ -510,11 +490,7 @@ func (c *clientWrapper) containerEACL(ctx context.Context, prm PrmContainerEACL)
start := time.Now() start := time.Now()
res, err := cl.ContainerEACL(ctx, cliPrm) res, err := cl.ContainerEACL(ctx, cliPrm)
c.incRequests(time.Since(start), methodContainerEACL) c.incRequests(time.Since(start), methodContainerEACL)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return eacl.Table{}, fmt.Errorf("get eacl on client: %w", err) return eacl.Table{}, fmt.Errorf("get eacl on client: %w", err)
} }
@ -537,13 +513,9 @@ func (c *clientWrapper) containerSetEACL(ctx context.Context, prm PrmContainerSe
} }
start := time.Now() start := time.Now()
res, err := cl.ContainerSetEACL(ctx, cliPrm) err = cl.ContainerSetEACL(ctx, cliPrm)
c.incRequests(time.Since(start), methodContainerSetEACL) c.incRequests(time.Since(start), methodContainerSetEACL)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return fmt.Errorf("set eacl on client: %w", err) return fmt.Errorf("set eacl on client: %w", err)
} }
@ -557,7 +529,7 @@ func (c *clientWrapper) containerSetEACL(ctx context.Context, prm PrmContainerSe
} }
err = waitForEACLPresence(ctx, c, cIDp, &prm.table, &prm.waitParams) err = waitForEACLPresence(ctx, c, cIDp, &prm.table, &prm.waitParams)
if err = c.handleError(nil, err); err != nil { if err = c.handleError(err); err != nil {
return fmt.Errorf("wait eacl presence on client: %w", err) return fmt.Errorf("wait eacl presence on client: %w", err)
} }
@ -574,11 +546,7 @@ func (c *clientWrapper) endpointInfo(ctx context.Context, _ prmEndpointInfo) (ne
start := time.Now() start := time.Now()
res, err := cl.EndpointInfo(ctx, sdkClient.PrmEndpointInfo{}) res, err := cl.EndpointInfo(ctx, sdkClient.PrmEndpointInfo{})
c.incRequests(time.Since(start), methodEndpointInfo) c.incRequests(time.Since(start), methodEndpointInfo)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return netmap.NodeInfo{}, fmt.Errorf("endpoint info on client: %w", err) return netmap.NodeInfo{}, fmt.Errorf("endpoint info on client: %w", err)
} }
@ -595,11 +563,7 @@ func (c *clientWrapper) networkInfo(ctx context.Context, _ prmNetworkInfo) (netm
start := time.Now() start := time.Now()
res, err := cl.NetworkInfo(ctx, sdkClient.PrmNetworkInfo{}) res, err := cl.NetworkInfo(ctx, sdkClient.PrmNetworkInfo{})
c.incRequests(time.Since(start), methodNetworkInfo) c.incRequests(time.Since(start), methodNetworkInfo)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return netmap.NetworkInfo{}, fmt.Errorf("network info on client: %w", err) return netmap.NetworkInfo{}, fmt.Errorf("network info on client: %w", err)
} }
@ -628,7 +592,7 @@ func (c *clientWrapper) objectPut(ctx context.Context, prm PrmObjectPut) (oid.ID
start := time.Now() start := time.Now()
wObj, err := cl.ObjectPutInit(ctx, cliPrm) wObj, err := cl.ObjectPutInit(ctx, cliPrm)
c.incRequests(time.Since(start), methodObjectPut) c.incRequests(time.Since(start), methodObjectPut)
if err = c.handleError(nil, err); err != nil { if err = c.handleError(err); err != nil {
return oid.ID{}, fmt.Errorf("init writing on API client: %w", err) return oid.ID{}, fmt.Errorf("init writing on API client: %w", err)
} }
@ -672,17 +636,13 @@ func (c *clientWrapper) objectPut(ctx context.Context, prm PrmObjectPut) (oid.ID
break break
} }
return oid.ID{}, fmt.Errorf("read payload: %w", c.handleError(nil, err)) return oid.ID{}, fmt.Errorf("read payload: %w", c.handleError(err))
} }
} }
} }
res, err := wObj.Close() res, err := wObj.Close()
var st apistatus.Status if err = c.handleError(err); err != nil { // here err already carries both status and client errors
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil { // here err already carries both status and client errors
return oid.ID{}, fmt.Errorf("client failure: %w", err) return oid.ID{}, fmt.Errorf("client failure: %w", err)
} }
@ -712,13 +672,9 @@ func (c *clientWrapper) objectDelete(ctx context.Context, prm PrmObjectDelete) e
} }
start := time.Now() start := time.Now()
res, err := cl.ObjectDelete(ctx, cliPrm) _, err = cl.ObjectDelete(ctx, cliPrm)
c.incRequests(time.Since(start), methodObjectDelete) c.incRequests(time.Since(start), methodObjectDelete)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return fmt.Errorf("delete object on client: %w", err) return fmt.Errorf("delete object on client: %w", err)
} }
return nil return nil
@ -749,7 +705,7 @@ func (c *clientWrapper) objectGet(ctx context.Context, prm PrmObjectGet) (ResGet
var res ResGetObject var res ResGetObject
rObj, err := cl.ObjectGetInit(ctx, cliPrm) rObj, err := cl.ObjectGetInit(ctx, cliPrm)
if err = c.handleError(nil, err); err != nil { if err = c.handleError(err); err != nil {
return ResGetObject{}, fmt.Errorf("init object reading on client: %w", err) return ResGetObject{}, fmt.Errorf("init object reading on client: %w", err)
} }
@ -757,12 +713,8 @@ func (c *clientWrapper) objectGet(ctx context.Context, prm PrmObjectGet) (ResGet
successReadHeader := rObj.ReadHeader(&res.Header) successReadHeader := rObj.ReadHeader(&res.Header)
c.incRequests(time.Since(start), methodObjectGet) c.incRequests(time.Since(start), methodObjectGet)
if !successReadHeader { if !successReadHeader {
rObjRes, err := rObj.Close() err = rObj.Close()
var st apistatus.Status err = c.handleError(err)
if rObjRes != nil {
st = rObjRes.Status()
}
err = c.handleError(st, err)
return res, fmt.Errorf("read header: %w", err) return res, fmt.Errorf("read header: %w", err)
} }
@ -806,11 +758,7 @@ func (c *clientWrapper) objectHead(ctx context.Context, prm PrmObjectHead) (obje
start := time.Now() start := time.Now()
res, err := cl.ObjectHead(ctx, cliPrm) res, err := cl.ObjectHead(ctx, cliPrm)
c.incRequests(time.Since(start), methodObjectHead) c.incRequests(time.Since(start), methodObjectHead)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return obj, fmt.Errorf("read object header via client: %w", err) return obj, fmt.Errorf("read object header via client: %w", err)
} }
if !res.ReadHeader(&obj) { if !res.ReadHeader(&obj) {
@ -846,7 +794,7 @@ func (c *clientWrapper) objectRange(ctx context.Context, prm PrmObjectRange) (Re
start := time.Now() start := time.Now()
res, err := cl.ObjectRangeInit(ctx, cliPrm) res, err := cl.ObjectRangeInit(ctx, cliPrm)
c.incRequests(time.Since(start), methodObjectRange) c.incRequests(time.Since(start), methodObjectRange)
if err = c.handleError(nil, err); err != nil { if err = c.handleError(err); err != nil {
return ResObjectRange{}, fmt.Errorf("init payload range reading on client: %w", err) return ResObjectRange{}, fmt.Errorf("init payload range reading on client: %w", err)
} }
@ -883,7 +831,7 @@ func (c *clientWrapper) objectSearch(ctx context.Context, prm PrmObjectSearch) (
} }
res, err := cl.ObjectSearchInit(ctx, cliPrm) res, err := cl.ObjectSearchInit(ctx, cliPrm)
if err = c.handleError(nil, err); err != nil { if err = c.handleError(err); err != nil {
return ResObjectSearch{}, fmt.Errorf("init object searching on client: %w", err) return ResObjectSearch{}, fmt.Errorf("init object searching on client: %w", err)
} }
@ -904,11 +852,7 @@ func (c *clientWrapper) sessionCreate(ctx context.Context, prm prmCreateSession)
start := time.Now() start := time.Now()
res, err := cl.SessionCreate(ctx, cliPrm) res, err := cl.SessionCreate(ctx, cliPrm)
c.incRequests(time.Since(start), methodSessionCreate) c.incRequests(time.Since(start), methodSessionCreate)
var st apistatus.Status if err = c.handleError(err); err != nil {
if res != nil {
st = res.Status()
}
if err = c.handleError(st, err); err != nil {
return resCreateSession{}, fmt.Errorf("session creation on client: %w", err) return resCreateSession{}, fmt.Errorf("session creation on client: %w", err)
} }
@ -978,25 +922,31 @@ func (c *clientWrapper) incRequests(elapsed time.Duration, method MethodIndex) {
} }
} }
func (c *clientStatusMonitor) handleError(st apistatus.Status, err error) error { func (c *clientStatusMonitor) handleError(err error) error {
if err != nil { if err == nil {
// non-status logic error that could be returned return nil
// from the SDK client; should not be considered
// as a connection error
var siErr *object.SplitInfoError
if !errors.As(err, &siErr) {
c.incErrorRate()
}
return err
} }
err = apistatus.ErrFromStatus(st) // count only this API errors
if errors.Is(err, apistatus.ErrServerInternal) || if errors.Is(err, apistatus.ErrServerInternal) ||
errors.Is(err, apistatus.ErrWrongMagicNumber) || errors.Is(err, apistatus.ErrWrongMagicNumber) ||
errors.Is(err, apistatus.ErrSignatureVerification) || errors.Is(err, apistatus.ErrSignatureVerification) ||
errors.Is(err, apistatus.ErrNodeUnderMaintenance) { errors.Is(err, apistatus.ErrNodeUnderMaintenance) {
c.incErrorRate() c.incErrorRate()
return err
}
// don't count another API errors
if errors.Is(err, apistatus.Error) {
return err
}
// non-status logic error that could be returned
// from the SDK client; should not be considered
// as a connection error
var siErr *object.SplitInfoError
if !errors.As(err, &siErr) {
c.incErrorRate()
} }
return err return err
@ -2132,8 +2082,7 @@ func (x *objectReadCloser) Read(p []byte) (int, error) {
// Close implements io.Closer of the object payload. // Close implements io.Closer of the object payload.
func (x *objectReadCloser) Close() error { func (x *objectReadCloser) Close() error {
_, err := x.reader.Close() return x.reader.Close()
return err
} }
// ResGetObject is designed to provide object header nad read one object payload from NeoFS system. // ResGetObject is designed to provide object header nad read one object payload from NeoFS system.
@ -2211,8 +2160,7 @@ func (x *ResObjectRange) Read(p []byte) (int, error) {
// Close ends reading the payload range and returns the result of the operation // Close ends reading the payload range and returns the result of the operation
// along with the final results. Must be called after using the ResObjectRange. // along with the final results. Must be called after using the ResObjectRange.
func (x *ResObjectRange) Close() error { func (x *ResObjectRange) Close() error {
_, err := x.payload.Close() return x.payload.Close()
return err
} }
// ObjectRange initiates reading an object's payload range through a remote // ObjectRange initiates reading an object's payload range through a remote
@ -2250,7 +2198,7 @@ type ResObjectSearch struct {
func (x *ResObjectSearch) Read(buf []oid.ID) (int, error) { func (x *ResObjectSearch) Read(buf []oid.ID) (int, error) {
n, ok := x.r.Read(buf) n, ok := x.r.Read(buf)
if !ok { if !ok {
_, err := x.r.Close() err := x.r.Close()
if err == nil { if err == nil {
return n, io.EOF return n, io.EOF
} }
@ -2272,7 +2220,7 @@ func (x *ResObjectSearch) Iterate(f func(oid.ID) bool) error {
// Close ends reading list of the matched objects and returns the result of the operation // Close ends reading list of the matched objects and returns the result of the operation
// along with the final results. Must be called after using the ResObjectSearch. // along with the final results. Must be called after using the ResObjectSearch.
func (x *ResObjectSearch) Close() { func (x *ResObjectSearch) Close() {
_, _ = x.r.Close() _ = x.r.Close()
} }
// SearchObjects initiates object selection through a remote server using NeoFS API protocol. // SearchObjects initiates object selection through a remote server using NeoFS API protocol.

View file

@ -521,75 +521,64 @@ func TestHandleError(t *testing.T) {
monitor := newClientStatusMonitor("", 10) monitor := newClientStatusMonitor("", 10)
for i, tc := range []struct { for i, tc := range []struct {
status apistatus.Status
err error err error
expectedError bool expectedError bool
countError bool countError bool
}{ }{
{ {
status: nil,
err: nil, err: nil,
expectedError: false, expectedError: false,
countError: false, countError: false,
}, },
{ {
status: apistatus.SuccessDefaultV2{},
err: nil, err: nil,
expectedError: false, expectedError: false,
countError: false, countError: false,
}, },
{ {
status: apistatus.SuccessDefaultV2{},
err: errors.New("error"), err: errors.New("error"),
expectedError: true, expectedError: true,
countError: true, countError: true,
}, },
{ {
status: nil,
err: errors.New("error"), err: errors.New("error"),
expectedError: true, expectedError: true,
countError: true, countError: true,
}, },
{ {
status: apistatus.ObjectNotFound{}, err: apistatus.ObjectNotFound{},
err: nil,
expectedError: true, expectedError: true,
countError: false, countError: false,
}, },
{ {
status: apistatus.ServerInternal{}, err: apistatus.ServerInternal{},
err: nil,
expectedError: true, expectedError: true,
countError: true, countError: true,
}, },
{ {
status: apistatus.WrongMagicNumber{}, err: apistatus.WrongMagicNumber{},
err: nil,
expectedError: true, expectedError: true,
countError: true, countError: true,
}, },
{ {
status: apistatus.SignatureVerification{}, err: apistatus.SignatureVerification{},
err: nil,
expectedError: true, expectedError: true,
countError: true, countError: true,
}, },
{ {
status: &apistatus.SignatureVerification{}, err: apistatus.SignatureVerification{},
err: nil,
expectedError: true, expectedError: true,
countError: true, countError: true,
}, },
{ {
status: apistatus.NodeUnderMaintenance{}, err: apistatus.NodeUnderMaintenance{},
err: nil,
expectedError: true, expectedError: true,
countError: true, countError: true,
}, },
} { } {
t.Run(strconv.Itoa(i), func(t *testing.T) { t.Run(strconv.Itoa(i), func(t *testing.T) {
errCount := monitor.currentErrorRate() errCount := monitor.currentErrorRate()
err := monitor.handleError(tc.status, tc.err) err := monitor.handleError(tc.err)
if tc.expectedError { if tc.expectedError {
require.Error(t, err) require.Error(t, err)
} else { } else {