forked from TrueCloudLab/frostfs-sdk-go
client: Replace panics with errors
Signed-off-by: Evgenii Baidakov <evgenii@nspcc.io>
This commit is contained in:
parent
8094342b1c
commit
f9d740487a
12 changed files with 98 additions and 53 deletions
|
@ -41,12 +41,14 @@ func (x ResBalanceGet) Amount() accounting.Decimal {
|
|||
// Any errors (local or remote, including returned status codes) are returned as Go errors,
|
||||
// see [apistatus] package for NeoFS-specific error types.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmBalanceGet docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingAccount]
|
||||
func (c *Client) BalanceGet(ctx context.Context, prm PrmBalanceGet) (*ResBalanceGet, error) {
|
||||
switch {
|
||||
case !prm.accountSet:
|
||||
panic("account not set")
|
||||
return nil, ErrMissingAccount
|
||||
}
|
||||
|
||||
// form request body
|
||||
|
|
|
@ -47,13 +47,6 @@ func writeXHeadersToMeta(xHeaders []string, h *v2session.RequestMetaHeader) {
|
|||
h.SetXHeaders(hs)
|
||||
}
|
||||
|
||||
// panic messages.
|
||||
const (
|
||||
panicMsgMissingContainer = "missing container"
|
||||
panicMsgMissingObject = "missing object"
|
||||
panicMsgOwnerExtract = "extract owner failed"
|
||||
)
|
||||
|
||||
// groups all the details required to send a single request and process a response to it.
|
||||
type contextCall struct {
|
||||
// ==================================================
|
||||
|
|
|
@ -84,13 +84,15 @@ func (c *Client) defaultSigner() neofscrypto.Signer {
|
|||
//
|
||||
// Success can be verified by reading by identifier (see ResContainerPut.ID).
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmContainerPut docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingContainer]
|
||||
func (c *Client) ContainerPut(ctx context.Context, prm PrmContainerPut) (*ResContainerPut, error) {
|
||||
// check parameters
|
||||
switch {
|
||||
case !prm.cnrSet:
|
||||
panic(panicMsgMissingContainer)
|
||||
return nil, ErrMissingContainer
|
||||
}
|
||||
|
||||
// TODO: check private signer is set before forming the request
|
||||
|
@ -204,12 +206,14 @@ func (x ResContainerGet) Container() container.Container {
|
|||
// Any errors (local or remote, including returned status codes) are returned as Go errors,
|
||||
// see [apistatus] package for NeoFS-specific error types.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmContainerGet docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingContainer]
|
||||
func (c *Client) ContainerGet(ctx context.Context, prm PrmContainerGet) (*ResContainerGet, error) {
|
||||
switch {
|
||||
case !prm.idSet:
|
||||
panic(panicMsgMissingContainer)
|
||||
return nil, ErrMissingContainer
|
||||
}
|
||||
|
||||
var cidV2 refs.ContainerID
|
||||
|
@ -292,13 +296,15 @@ func (x ResContainerList) Containers() []cid.ID {
|
|||
// Any errors (local or remote, including returned status codes) are returned as Go errors,
|
||||
// see [apistatus] package for NeoFS-specific error types.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmContainerList docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingAccount]
|
||||
func (c *Client) ContainerList(ctx context.Context, prm PrmContainerList) (*ResContainerList, error) {
|
||||
// check parameters
|
||||
switch {
|
||||
case !prm.ownerSet:
|
||||
panic("account not set")
|
||||
return nil, ErrMissingAccount
|
||||
}
|
||||
|
||||
// form request body
|
||||
|
@ -396,15 +402,17 @@ func (x *PrmContainerDelete) WithinSession(tok session.Container) {
|
|||
//
|
||||
// Success can be verified by reading by identifier (see GetContainer).
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmContainerDelete docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingContainer]
|
||||
//
|
||||
// Reflects all internal errors in second return value (transport problems, response processing, etc.).
|
||||
func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) error {
|
||||
// check parameters
|
||||
switch {
|
||||
case !prm.idSet:
|
||||
panic(panicMsgMissingContainer)
|
||||
return ErrMissingContainer
|
||||
}
|
||||
|
||||
// sign container ID
|
||||
|
@ -502,13 +510,15 @@ func (x ResContainerEACL) Table() eacl.Table {
|
|||
// Any errors (local or remote, including returned status codes) are returned as Go errors,
|
||||
// see [apistatus] package for NeoFS-specific error types.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmContainerEACL docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingContainer]
|
||||
func (c *Client) ContainerEACL(ctx context.Context, prm PrmContainerEACL) (*ResContainerEACL, error) {
|
||||
// check parameters
|
||||
switch {
|
||||
case !prm.idSet:
|
||||
panic(panicMsgMissingContainer)
|
||||
return nil, ErrMissingContainer
|
||||
}
|
||||
|
||||
var cidV2 refs.ContainerID
|
||||
|
@ -609,18 +619,21 @@ func (x *PrmContainerSetEACL) WithinSession(s session.Container) {
|
|||
//
|
||||
// Success can be verified by reading by identifier (see EACL).
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmContainerSetEACL docs).
|
||||
// Return errors:
|
||||
// - [ErrMissingEACL]
|
||||
// - [ErrMissingEACLContainer]
|
||||
//
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL) error {
|
||||
// check parameters
|
||||
switch {
|
||||
case !prm.tableSet:
|
||||
panic("eACL table not set")
|
||||
return ErrMissingEACL
|
||||
}
|
||||
|
||||
_, isCIDSet := prm.table.CID()
|
||||
if !isCIDSet {
|
||||
panic("missing container in eACL table")
|
||||
return ErrMissingEACLContainer
|
||||
}
|
||||
|
||||
// sign the eACL table
|
||||
|
@ -708,13 +721,15 @@ func (x *PrmAnnounceSpace) SetValues(vs []container.SizeEstimation) {
|
|||
//
|
||||
// At this moment success can not be checked.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmAnnounceSpace docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingAnnouncements]
|
||||
func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, prm PrmAnnounceSpace) error {
|
||||
// check parameters
|
||||
switch {
|
||||
case len(prm.announcements) == 0:
|
||||
panic("missing announcements")
|
||||
return ErrMissingAnnouncements
|
||||
}
|
||||
|
||||
// convert list of SDK announcement structures into NeoFS-API v2 list
|
||||
|
|
|
@ -1,10 +1,25 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrMissingContainer = errors.New("missing container")
|
||||
ErrMissingObject = errors.New("missing object")
|
||||
ErrMissingAccount = errors.New("missing account")
|
||||
ErrMissingEACL = errors.New("missing eACL table")
|
||||
ErrMissingEACLContainer = errors.New("missing container in eACL table")
|
||||
ErrMissingAnnouncements = errors.New("missing announcements")
|
||||
ErrZeroRangeLength = errors.New("zero range length")
|
||||
ErrMissingRanges = errors.New("missing ranges")
|
||||
ErrZeroEpoch = errors.New("zero epoch")
|
||||
ErrMissingTrusts = errors.New("missing trusts")
|
||||
ErrMissingTrust = errors.New("missing trust")
|
||||
|
||||
ErrUnexpectedReadCall = errors.New("unexpected call to `Read`")
|
||||
|
||||
errMissingResponseField missingResponseFieldErr
|
||||
)
|
||||
|
||||
|
|
|
@ -114,11 +114,12 @@ func (x ResObjectDelete) Tombstone() oid.ID {
|
|||
// Any client's internal or transport errors are returned as `error`,
|
||||
// see [apistatus] package for NeoFS-specific error types.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmObjectDelete docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - global (see Client docs)
|
||||
// - [ErrMissingContainer];
|
||||
// - [ErrMissingObject];
|
||||
// - [apistatus.ErrContainerNotFound];
|
||||
// - [apistatus.ErrObjectAccessDenied];
|
||||
// - [apistatus.ErrObjectLocked];
|
||||
|
@ -126,9 +127,9 @@ func (x ResObjectDelete) Tombstone() oid.ID {
|
|||
func (c *Client) ObjectDelete(ctx context.Context, prm PrmObjectDelete) (*ResObjectDelete, error) {
|
||||
switch {
|
||||
case prm.addr.GetContainerID() == nil:
|
||||
panic(panicMsgMissingContainer)
|
||||
return nil, ErrMissingContainer
|
||||
case prm.addr.GetObjectID() == nil:
|
||||
panic(panicMsgMissingObject)
|
||||
return nil, ErrMissingObject
|
||||
}
|
||||
|
||||
// form request body
|
||||
|
|
|
@ -289,15 +289,18 @@ func (x *ObjectReader) Read(p []byte) (int, error) {
|
|||
// The call only opens the transmission channel, explicit fetching is done using the ObjectReader.
|
||||
// Exactly one return value is non-nil. Resulting reader must be finally closed.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmObjectGet docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingContainer]
|
||||
// - [ErrMissingObject]
|
||||
func (c *Client) ObjectGetInit(ctx context.Context, prm PrmObjectGet) (*ObjectReader, error) {
|
||||
// check parameters
|
||||
switch {
|
||||
case prm.addr.GetContainerID() == nil:
|
||||
panic(panicMsgMissingContainer)
|
||||
return nil, ErrMissingContainer
|
||||
case prm.addr.GetObjectID() == nil:
|
||||
panic(panicMsgMissingObject)
|
||||
return nil, ErrMissingObject
|
||||
}
|
||||
|
||||
// form request body
|
||||
|
@ -385,11 +388,12 @@ func (x *ResObjectHead) ReadHeader(dst *object.Object) bool {
|
|||
// Any client's internal or transport errors are returned as `error`,
|
||||
// see [apistatus] package for NeoFS-specific error types.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmObjectHead docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - global (see Client docs);
|
||||
// - [ErrMissingContainer];
|
||||
// - [ErrMissingObject];
|
||||
// - *[object.SplitInfoError] (returned on virtual objects with PrmObjectHead.MakeRaw).
|
||||
// - [apistatus.ErrContainerNotFound];
|
||||
// - [apistatus.ErrObjectNotFound];
|
||||
|
@ -399,9 +403,9 @@ func (x *ResObjectHead) ReadHeader(dst *object.Object) bool {
|
|||
func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectHead, error) {
|
||||
switch {
|
||||
case prm.addr.GetContainerID() == nil:
|
||||
panic(panicMsgMissingContainer)
|
||||
return nil, ErrMissingContainer
|
||||
case prm.addr.GetObjectID() == nil:
|
||||
panic(panicMsgMissingObject)
|
||||
return nil, ErrMissingObject
|
||||
}
|
||||
|
||||
var body v2object.HeadRequestBody
|
||||
|
@ -635,17 +639,21 @@ func (x *ObjectRangeReader) Read(p []byte) (int, error) {
|
|||
// The call only opens the transmission channel, explicit fetching is done using the ObjectRangeReader.
|
||||
// Exactly one return value is non-nil. Resulting reader must be finally closed.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmObjectRange docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingContainer]
|
||||
// - [ErrMissingObject]
|
||||
// - [ErrZeroRangeLength]
|
||||
func (c *Client) ObjectRangeInit(ctx context.Context, prm PrmObjectRange) (*ObjectRangeReader, error) {
|
||||
// check parameters
|
||||
switch {
|
||||
case prm.addr.GetContainerID() == nil:
|
||||
panic(panicMsgMissingContainer)
|
||||
return nil, ErrMissingContainer
|
||||
case prm.addr.GetObjectID() == nil:
|
||||
panic(panicMsgMissingObject)
|
||||
return nil, ErrMissingObject
|
||||
case prm.rng.GetLength() == 0:
|
||||
panic("zero range length")
|
||||
return nil, ErrZeroRangeLength
|
||||
}
|
||||
|
||||
// form request body
|
||||
|
|
|
@ -152,16 +152,19 @@ func (x ResObjectHash) Checksums() [][]byte {
|
|||
// Any client's internal or transport errors are returned as `error`,
|
||||
// see [apistatus] package for NeoFS-specific error types.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmObjectHash docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingContainer]
|
||||
// - [ErrMissingObject]
|
||||
func (c *Client) ObjectHash(ctx context.Context, prm PrmObjectHash) (*ResObjectHash, error) {
|
||||
switch {
|
||||
case prm.addr.GetContainerID() == nil:
|
||||
panic(panicMsgMissingContainer)
|
||||
return nil, ErrMissingContainer
|
||||
case prm.addr.GetObjectID() == nil:
|
||||
panic(panicMsgMissingObject)
|
||||
return nil, ErrMissingObject
|
||||
case len(prm.body.GetRanges()) == 0:
|
||||
panic("missing ranges")
|
||||
return nil, ErrMissingRanges
|
||||
}
|
||||
|
||||
prm.body.SetAddress(&prm.addr)
|
||||
|
|
|
@ -205,13 +205,15 @@ func (x *ObjectListReader) Close() error {
|
|||
// is done using the ObjectListReader. Exactly one return value is non-nil.
|
||||
// Resulting reader must be finally closed.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmObjectSearch docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrMissingContainer]
|
||||
func (c *Client) ObjectSearchInit(ctx context.Context, prm PrmObjectSearch) (*ObjectListReader, error) {
|
||||
// check parameters
|
||||
switch {
|
||||
case !prm.cnrSet:
|
||||
panic(panicMsgMissingContainer)
|
||||
return nil, ErrMissingContainer
|
||||
}
|
||||
|
||||
var cidV2 v2refs.ContainerID
|
||||
|
|
|
@ -136,7 +136,7 @@ func (s *singleStreamResponder) Read(resp *v2object.SearchResponse) error {
|
|||
if s.endError != nil {
|
||||
return s.endError
|
||||
}
|
||||
panic("unexpected call to `Read`")
|
||||
return ErrUnexpectedReadCall
|
||||
}
|
||||
|
||||
var body v2object.SearchResponseBody
|
||||
|
|
|
@ -37,15 +37,18 @@ func (x *PrmAnnounceLocalTrust) SetValues(trusts []reputation.Trust) {
|
|||
// Any errors (local or remote, including returned status codes) are returned as Go errors,
|
||||
// see [apistatus] package for NeoFS-specific error types.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmAnnounceLocalTrust docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrZeroEpoch]
|
||||
// - [ErrMissingTrusts]
|
||||
func (c *Client) AnnounceLocalTrust(ctx context.Context, prm PrmAnnounceLocalTrust) error {
|
||||
// check parameters
|
||||
switch {
|
||||
case prm.epoch == 0:
|
||||
panic("zero epoch")
|
||||
return ErrZeroEpoch
|
||||
case len(prm.trusts) == 0:
|
||||
panic("missing trusts")
|
||||
return ErrMissingTrusts
|
||||
}
|
||||
|
||||
// form request body
|
||||
|
@ -123,15 +126,18 @@ func (x *PrmAnnounceIntermediateTrust) SetCurrentValue(trust reputation.PeerToPe
|
|||
// Any errors (local or remote, including returned status codes) are returned as Go errors,
|
||||
// see [apistatus] package for NeoFS-specific error types.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmAnnounceIntermediateTrust docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Return errors:
|
||||
// - [ErrZeroEpoch]
|
||||
// - [ErrMissingTrust]
|
||||
func (c *Client) AnnounceIntermediateTrust(ctx context.Context, prm PrmAnnounceIntermediateTrust) error {
|
||||
// check parameters
|
||||
switch {
|
||||
case prm.epoch == 0:
|
||||
panic("zero epoch")
|
||||
return ErrZeroEpoch
|
||||
case !prm.trustSet:
|
||||
panic("current trust value not set")
|
||||
return ErrMissingTrust
|
||||
}
|
||||
|
||||
var trust v2reputation.PeerToPeerTrust
|
||||
|
|
|
@ -2,6 +2,7 @@ package client
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
|
||||
|
@ -64,12 +65,11 @@ func (x ResSessionCreate) PublicKey() []byte {
|
|||
// Any errors (local or remote, including returned status codes) are returned as Go errors,
|
||||
// see [apistatus] package for NeoFS-specific error types.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see PrmSessionCreate docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
func (c *Client) SessionCreate(ctx context.Context, prm PrmSessionCreate) (*ResSessionCreate, error) {
|
||||
var ownerID user.ID
|
||||
if err := user.IDFromSigner(&ownerID, prm.signer); err != nil {
|
||||
panic(panicMsgOwnerExtract)
|
||||
return nil, fmt.Errorf("IDFromSigner: %w", err)
|
||||
}
|
||||
|
||||
var ownerIDV2 refs.OwnerID
|
||||
|
|
|
@ -155,7 +155,7 @@ func (x commonData) signedData(w contextWriter) []byte {
|
|||
|
||||
func (x *commonData) sign(signer neofscrypto.Signer, w contextWriter) error {
|
||||
if err := user.IDFromSigner(&x.issuer, signer); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("IDFromSigner: %w", err)
|
||||
}
|
||||
|
||||
x.issuerSet = true
|
||||
|
|
Loading…
Add table
Reference in a new issue