[#275] client: Return status from all methods #275

Merged
alexvanin merged 1 commit from mbiryukova/frostfs-sdk-go:bugfix/client_status into master 2024-09-26 10:33:03 +00:00
8 changed files with 14 additions and 38 deletions

View file

@ -65,7 +65,7 @@ func (c *Client) APEManagerListChains(ctx context.Context, prm PrmAPEManagerList
var res ResAPEManagerListChains
res.st, err = c.processResponse(resp)
if err != nil || !apistatus.IsSuccessful(res.st) {
return nil, err
return &res, err
}
for _, ch := range resp.GetBody().GetChains() {

View file

@ -239,12 +239,8 @@ func (c *Client) NetMapSnapshot(ctx context.Context, _ PrmNetMapSnapshot) (*ResN
var res ResNetMapSnapshot
res.st, err = c.processResponse(resp)
if err != nil {
return nil, err
}
if !apistatus.IsSuccessful(res.st) {
return &res, nil
if err != nil || !apistatus.IsSuccessful(res.st) {
return &res, err
}
const fieldNetMap = "network map"

View file

@ -148,12 +148,8 @@ func (c *Client) ObjectDelete(ctx context.Context, prm PrmObjectDelete) (*ResObj
var res ResObjectDelete
res.st, err = c.processResponse(resp)
if err != nil {
return nil, err
}
if !apistatus.IsSuccessful(res.st) {
return &res, nil
if err != nil || !apistatus.IsSuccessful(res.st) {
return &res, err
}
const fieldTombstone = "tombstone"

View file

@ -492,12 +492,8 @@ func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectH
var res ResObjectHead
res.st, err = c.processResponse(resp)
if err != nil {
return nil, err
}
if !apistatus.IsSuccessful(res.st) {
return &res, nil
if err != nil || !apistatus.IsSuccessful(res.st) {
return &res, err
}
res.idObj = *prm.ObjectID

View file

@ -189,12 +189,8 @@ func (c *Client) ObjectHash(ctx context.Context, prm PrmObjectHash) (*ResObjectH
var res ResObjectHash
res.st, err = c.processResponse(resp)
if err != nil {
return nil, err
}
if !apistatus.IsSuccessful(res.st) {
return &res, nil
if err != nil || !apistatus.IsSuccessful(res.st) {
return &res, err
}
res.checksums = resp.GetBody().GetHashList()

View file

@ -246,12 +246,8 @@ func (x *objectPatcher) Close(_ context.Context) (*ResObjectPatch, error) {
}
x.res.st, x.err = x.client.processResponse(&x.respV2)
if x.err != nil {
return nil, x.err
}
if !apistatus.IsSuccessful(x.res.st) {
return &x.res, nil
if x.err != nil || !apistatus.IsSuccessful(x.res.st) {
return &x.res, x.err
}
const fieldID = "ID"

View file

@ -156,12 +156,8 @@ func (x *objectWriterRaw) Close(_ context.Context) (*ResObjectPut, error) {
}
x.res.st, x.err = x.client.processResponse(&x.respV2)
if x.err != nil {
return nil, x.err
}
if !apistatus.IsSuccessful(x.res.st) {
return &x.res, nil
if x.err != nil || !apistatus.IsSuccessful(x.res.st) {
Review

It seems that then the errors may not be distinguished: either the error occurred by performing a request (signature check failure) or by processing of request (APE check failure while PutObject handling).
Although, we have such an error resolution:

func (c *Client) processResponse(resp responseV2) (apistatus.Status, error) {
	if c.prm.ResponseInfoCallback != nil {
		rmi := ResponseMetaInfo{
			key:   resp.GetVerificationHeader().GetBodySignature().GetKey(),
			epoch: resp.GetMetaHeader().GetEpoch(),
		}
		if err := c.prm.ResponseInfoCallback(rmi); err != nil {
			return nil, fmt.Errorf("response callback error: %w", err)
		}
	}

	err := signature.VerifyServiceMessage(resp)
	if err != nil {
		return nil, fmt.Errorf("invalid response signature: %w", err)
	}

	st := apistatus.FromStatusV2(resp.GetMetaHeader().GetStatus())
	if !c.prm.DisableFrostFSErrorResolution {
		return st, apistatus.ErrFromStatus(st)
	}
	return st, nil
}

that doesn't seem controversial to the introduced approach

It seems that then the errors may **not** be distinguished: either the error occurred by _performing_ a request (signature check failure) or by _processing_ of request (APE check failure while `PutObject` handling). Although, we have such an error resolution: ```go func (c *Client) processResponse(resp responseV2) (apistatus.Status, error) { if c.prm.ResponseInfoCallback != nil { rmi := ResponseMetaInfo{ key: resp.GetVerificationHeader().GetBodySignature().GetKey(), epoch: resp.GetMetaHeader().GetEpoch(), } if err := c.prm.ResponseInfoCallback(rmi); err != nil { return nil, fmt.Errorf("response callback error: %w", err) } } err := signature.VerifyServiceMessage(resp) if err != nil { return nil, fmt.Errorf("invalid response signature: %w", err) } st := apistatus.FromStatusV2(resp.GetMetaHeader().GetStatus()) if !c.prm.DisableFrostFSErrorResolution { return st, apistatus.ErrFromStatus(st) } return st, nil } ``` that doesn't seem controversial to the introduced approach
return &x.res, x.err
}
const fieldID = "ID"

View file

@ -167,7 +167,7 @@ func (c *Client) ObjectPutSingle(ctx context.Context, prm PrmObjectPutSingle) (*
var res ResObjectPutSingle
res.st, err = c.processResponse(resp)
if err != nil {
return nil, err
return &res, err
}
res.epoch = resp.GetMetaHeader().GetEpoch()