sdk: Remove panic from RPCs #15

Merged
acid-ant merged 2 commits from bugfix/2-do-not-panic into master 2023-03-01 07:29:23 +00:00
17 changed files with 92 additions and 90 deletions

View file

@ -32,15 +32,12 @@ linters:
- revive
# some default golangci-lint linters
- deadcode
- errcheck
fyrchik commented 2023-02-17 08:50:16 +00:00 (Migrated from github.com)
Review

Why?

Why?
acid-ant commented 2023-02-17 14:06:18 +00:00 (Migrated from github.com)
Review

Deprecated since v1.49.0 of golangci-lint. Replaced by unused.

Deprecated since v1.49.0 of golangci-lint. Replaced by `unused`.
- gosimple
- ineffassign
- staticcheck
- structcheck
- typecheck
- unused
- varcheck
# extra linters
- exhaustive

View file

@ -46,7 +46,7 @@ func (x ResBalanceGet) Amount() accounting.Decimal {
// FrostFS status codes are returned as `error`, otherwise, are included
fyrchik commented 2023-02-24 14:31:06 +00:00 (Migrated from github.com)
Review

an error

`an error`
fyrchik commented 2023-02-24 14:31:55 +00:00 (Migrated from github.com)
Review

What about adding a variable for this and other errors touched in this commit?

What about adding a variable for this and other errors touched in this commit?
acid-ant commented 2023-02-27 08:01:25 +00:00 (Migrated from github.com)
Review

Fixed.

Fixed.
acid-ant commented 2023-02-27 08:04:30 +00:00 (Migrated from github.com)
Review

Sounds good, added.

Sounds good, added.
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmBalanceGet docs).
// Returns an error if parameters are set incorrectly (see PrmBalanceGet docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -54,9 +54,9 @@ func (x ResBalanceGet) Amount() accounting.Decimal {
func (c *Client) BalanceGet(ctx context.Context, prm PrmBalanceGet) (*ResBalanceGet, error) {
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case !prm.accountSet:
panic("account not set")
return nil, errorAccountNotSet
}
// form request body

View file

@ -69,7 +69,7 @@ func (c *Client) Init(prm PrmInit) {
// argument, otherwise context.Background() is used. Dial returns context
// errors, see context package docs for details.
//
// Panics if required parameters are set incorrectly, look carefully
// Returns an error if required parameters are set incorrectly, look carefully
// at the method documentation.
//
// One-time method call during application start-up stage (after Init ) is expected.
@ -78,12 +78,12 @@ func (c *Client) Init(prm PrmInit) {
// See also Init / Close.
func (c *Client) Dial(prm PrmDial) error {
if prm.endpoint == "" {
panic("server address is unset or empty")
return errorServerAddrUnset
}
if prm.timeoutDialSet {
if prm.timeoutDial <= 0 {
panic("non-positive timeout")
return errorNonPositiveTimeout
}
} else {
prm.timeoutDial = 5 * time.Second
@ -91,7 +91,7 @@ func (c *Client) Dial(prm PrmDial) error {
if prm.streamTimeoutSet {
if prm.streamTimeout <= 0 {
panic("non-positive timeout")
return errorNonPositiveTimeout
}
} else {
prm.streamTimeout = 10 * time.Second

View file

@ -2,6 +2,7 @@ package client
import (
"crypto/ecdsa"
"errors"
"fmt"
"github.com/TrueCloudLab/frostfs-api-go/v2/refs"
@ -70,11 +71,21 @@ func writeXHeadersToMeta(xHeaders []string, h *v2session.RequestMetaHeader) {
h.SetXHeaders(hs)
}
// panic messages.
const (
panicMsgMissingContext = "missing context"
panicMsgMissingContainer = "missing container"
panicMsgMissingObject = "missing object"
// error messages.
var (
errorMissingContext = errors.New("missing context")
errorMissingContainer = errors.New("missing container")
errorMissingObject = errors.New("missing object")
errorAccountNotSet = errors.New("account not set")
errorServerAddrUnset = errors.New("server address is unset or empty")
errorNonPositiveTimeout = errors.New("non-positive timeout")
errorEACLTableNotSet = errors.New("eACL table not set")
errorMissingAnnouncements = errors.New("missing announcements")
errorZeroRangeLength = errors.New("zero range length")
errorMissingRanges = errors.New("missing ranges")
errorZeroEpoch = errors.New("zero epoch")
errorMissingTrusts = errors.New("missing trusts")
errorTrustNotSet = errors.New("current trust value not set")
)
// groups all the details required to send a single request and process a response to it.

View file

@ -77,7 +77,7 @@ func (x ResContainerPut) ID() cid.ID {
//
// Success can be verified by reading by identifier (see ResContainerPut.ID).
//
// Immediately panics if parameters are set incorrectly (see PrmContainerPut docs).
// Returns an error if parameters are set incorrectly (see PrmContainerPut docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -86,9 +86,9 @@ func (c *Client) ContainerPut(ctx context.Context, prm PrmContainerPut) (*ResCon
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case !prm.cnrSet:
panic(panicMsgMissingContainer)
return nil, errorMissingContainer
}
// TODO: check private key is set before forming the request
@ -204,7 +204,7 @@ func (x ResContainerGet) Container() container.Container {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmContainerGet docs).
// Returns an error if parameters are set incorrectly (see PrmContainerGet docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -213,9 +213,9 @@ func (x ResContainerGet) Container() container.Container {
func (c *Client) ContainerGet(ctx context.Context, prm PrmContainerGet) (*ResContainerGet, error) {
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case !prm.idSet:
panic(panicMsgMissingContainer)
return nil, errorMissingContainer
}
var cidV2 refs.ContainerID
@ -304,7 +304,7 @@ func (x ResContainerList) Containers() []cid.ID {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmContainerList docs).
// Returns an error if parameters are set incorrectly (see PrmContainerList docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -313,9 +313,9 @@ func (c *Client) ContainerList(ctx context.Context, prm PrmContainerList) (*ResC
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case !prm.ownerSet:
panic("account not set")
return nil, errorAccountNotSet
}
// form request body
@ -413,7 +413,7 @@ type ResContainerDelete struct {
//
// Success can be verified by reading by identifier (see GetContainer).
//
// Immediately panics if parameters are set incorrectly (see PrmContainerDelete docs).
// Returns an error if parameters are set incorrectly (see PrmContainerDelete docs).
// 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.
@ -425,9 +425,9 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case !prm.idSet:
panic(panicMsgMissingContainer)
return nil, errorMissingContainer
}
// sign container ID
@ -528,7 +528,7 @@ func (x ResContainerEACL) Table() eacl.Table {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmContainerEACL docs).
// Returns an error if parameters are set incorrectly (see PrmContainerEACL docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -539,9 +539,9 @@ func (c *Client) ContainerEACL(ctx context.Context, prm PrmContainerEACL) (*ResC
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case !prm.idSet:
panic(panicMsgMissingContainer)
return nil, errorMissingContainer
}
var cidV2 refs.ContainerID
@ -642,7 +642,7 @@ type ResContainerSetEACL struct {
//
// Success can be verified by reading by identifier (see EACL).
//
// Immediately panics if parameters are set incorrectly (see PrmContainerSetEACL docs).
// Returns an error if parameters are set incorrectly (see PrmContainerSetEACL docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -651,9 +651,9 @@ func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL)
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case !prm.tableSet:
panic("eACL table not set")
return nil, errorEACLTableNotSet
}
// sign the eACL table
@ -747,7 +747,7 @@ type ResAnnounceSpace struct {
//
// At this moment success can not be checked.
//
// Immediately panics if parameters are set incorrectly (see PrmAnnounceSpace docs).
// Returns an error if parameters are set incorrectly (see PrmAnnounceSpace docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -756,9 +756,9 @@ func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, prm PrmAnnounce
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case len(prm.announcements) == 0:
panic("missing announcements")
return nil, errorMissingAnnouncements
}
// convert list of SDK announcement structures into FrostFS-API v2 list

View file

@ -47,7 +47,7 @@ func (x ResEndpointInfo) NodeInfo() netmap.NodeInfo {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmEndpointInfo docs).
// Returns an error if parameters are set incorrectly (see PrmEndpointInfo docs).
// 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 ResEndpointInfo.
@ -58,7 +58,7 @@ func (x ResEndpointInfo) NodeInfo() netmap.NodeInfo {
func (c *Client) EndpointInfo(ctx context.Context, prm PrmEndpointInfo) (*ResEndpointInfo, error) {
// check context
if ctx == nil {
panic(panicMsgMissingContext)
return nil, errorMissingContext
}
// form request
@ -144,7 +144,7 @@ func (x ResNetworkInfo) Info() netmap.NetworkInfo {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmNetworkInfo docs).
// Returns an error if parameters are set incorrectly (see PrmNetworkInfo docs).
// 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 ResNetworkInfo.
@ -155,7 +155,7 @@ func (x ResNetworkInfo) Info() netmap.NetworkInfo {
func (c *Client) NetworkInfo(ctx context.Context, prm PrmNetworkInfo) (*ResNetworkInfo, error) {
// check context
if ctx == nil {
panic(panicMsgMissingContext)
return nil, errorMissingContext
}
// form request
@ -224,6 +224,7 @@ func (x ResNetMapSnapshot) NetMap() netmap.NetMap {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Returns an error if parameters are set incorrectly.
// 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 ResNetMapSnapshot.
@ -234,7 +235,7 @@ func (x ResNetMapSnapshot) NetMap() netmap.NetMap {
func (c *Client) NetMapSnapshot(ctx context.Context, _ PrmNetMapSnapshot) (*ResNetMapSnapshot, error) {
// check context
if ctx == nil {
panic(panicMsgMissingContext)
return nil, errorMissingContext
}
// form request body

View file

@ -70,10 +70,9 @@ func TestClient_NetMapSnapshot(t *testing.T) {
ctx := context.Background()
// missing context
require.PanicsWithValue(t, panicMsgMissingContext, func() {
//nolint:staticcheck
_, _ = c.NetMapSnapshot(nil, prm)
})
//nolint:staticcheck
_, err = c.NetMapSnapshot(nil, prm)
require.ErrorIs(t, err, errorMissingContext, "")
// request signature
srv.errTransport = errors.New("any error")

View file

@ -114,7 +114,7 @@ func (x ResObjectDelete) Tombstone() oid.ID {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmObjectDelete docs).
// Returns an error if parameters are set incorrectly (see PrmObjectDelete docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -126,11 +126,11 @@ func (x ResObjectDelete) Tombstone() oid.ID {
func (c *Client) ObjectDelete(ctx context.Context, prm PrmObjectDelete) (*ResObjectDelete, error) {
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case prm.addr.GetContainerID() == nil:
panic(panicMsgMissingContainer)
return nil, errorMissingContainer
case prm.addr.GetObjectID() == nil:
panic(panicMsgMissingObject)
return nil, errorMissingObject
}
// form request body

View file

@ -296,17 +296,17 @@ 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).
// Returns an error if parameters are set incorrectly (see PrmObjectGet docs).
// Context is required and must not be nil. It is used for network communication.
func (c *Client) ObjectGetInit(ctx context.Context, prm PrmObjectGet) (*ObjectReader, error) {
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case prm.addr.GetContainerID() == nil:
panic(panicMsgMissingContainer)
return nil, errorMissingContainer
case prm.addr.GetObjectID() == nil:
panic(panicMsgMissingObject)
return nil, errorMissingObject
}
// form request body
@ -400,7 +400,7 @@ func (x *ResObjectHead) ReadHeader(dst *object.Object) bool {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmObjectHead docs).
// Returns an error if parameters are set incorrectly (see PrmObjectHead docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return errors:
@ -417,11 +417,11 @@ func (x *ResObjectHead) ReadHeader(dst *object.Object) bool {
func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectHead, error) {
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case prm.addr.GetContainerID() == nil:
panic(panicMsgMissingContainer)
return nil, errorMissingContainer
case prm.addr.GetObjectID() == nil:
panic(panicMsgMissingObject)
return nil, errorMissingObject
}
var body v2object.HeadRequestBody
@ -663,19 +663,19 @@ 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).
// Returns an error if parameters are set incorrectly (see PrmObjectRange docs).
// Context is required and must not be nil. It is used for network communication.
func (c *Client) ObjectRangeInit(ctx context.Context, prm PrmObjectRange) (*ObjectRangeReader, error) {
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case prm.addr.GetContainerID() == nil:
panic(panicMsgMissingContainer)
return nil, errorMissingContainer
case prm.addr.GetObjectID() == nil:
panic(panicMsgMissingObject)
return nil, errorMissingObject
case prm.rng.GetLength() == 0:
panic("zero range length")
return nil, errorZeroRangeLength
}
// form request body

View file

@ -154,7 +154,7 @@ func (x ResObjectHash) Checksums() [][]byte {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmObjectHash docs).
// Returns an error if parameters are set incorrectly (see PrmObjectHash docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -167,13 +167,13 @@ func (x ResObjectHash) Checksums() [][]byte {
func (c *Client) ObjectHash(ctx context.Context, prm PrmObjectHash) (*ResObjectHash, error) {
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case prm.addr.GetContainerID() == nil:
panic(panicMsgMissingContainer)
return nil, errorMissingContainer
case prm.addr.GetObjectID() == nil:
panic(panicMsgMissingObject)
return nil, errorMissingObject
case len(prm.body.GetRanges()) == 0:
panic("missing ranges")
return nil, errorMissingRanges
}
prm.body.SetAddress(&prm.addr)

View file

@ -235,11 +235,12 @@ func (x *ObjectWriter) Close() (*ResObjectPut, error) {
// The call only opens the transmission channel, explicit recording is done using the ObjectWriter.
// Exactly one return value is non-nil. Resulting writer must be finally closed.
//
// Returns an error if parameters are set incorrectly.
// Context is required and must not be nil. It is used for network communication.
func (c *Client) ObjectPutInit(ctx context.Context, prm PrmObjectPutInit) (*ObjectWriter, error) {
// check parameters
if ctx == nil {
panic(panicMsgMissingContext)
return nil, errorMissingContext
}
var w ObjectWriter

View file

@ -218,15 +218,15 @@ func (x *ObjectListReader) Close() (*ResObjectSearch, 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).
// Returns an error if parameters are set incorrectly (see PrmObjectSearch docs).
// Context is required and must not be nil. It is used for network communication.
func (c *Client) ObjectSearchInit(ctx context.Context, prm PrmObjectSearch) (*ObjectListReader, error) {
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case !prm.cnrSet:
panic(panicMsgMissingContainer)
return nil, errorMissingContainer
}
var cidV2 v2refs.ContainerID

View file

@ -45,7 +45,7 @@ type ResAnnounceLocalTrust struct {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmAnnounceLocalTrust docs).
// Returns an error if parameters are set incorrectly (see PrmAnnounceLocalTrust docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -54,11 +54,11 @@ func (c *Client) AnnounceLocalTrust(ctx context.Context, prm PrmAnnounceLocalTru
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case prm.epoch == 0:
panic("zero epoch")
return nil, errorZeroEpoch
case len(prm.trusts) == 0:
panic("missing trusts")
return nil, errorMissingTrusts
}
// form request body
@ -146,7 +146,7 @@ type ResAnnounceIntermediateTrust struct {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmAnnounceIntermediateTrust docs).
// Returns an error if parameters are set incorrectly (see PrmAnnounceIntermediateTrust docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -155,11 +155,11 @@ func (c *Client) AnnounceIntermediateTrust(ctx context.Context, prm PrmAnnounceI
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
return nil, errorMissingContext
case prm.epoch == 0:
panic("zero epoch")
return nil, errorZeroEpoch
case !prm.trustSet:
panic("current trust value not set")
return nil, errorTrustNotSet
}
var trust v2reputation.PeerToPeerTrust

View file

@ -72,7 +72,7 @@ func (x ResSessionCreate) PublicKey() []byte {
// FrostFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
//
// Immediately panics if parameters are set incorrectly (see PrmSessionCreate docs).
// Returns an error if parameters are set incorrectly (see PrmSessionCreate docs).
// Context is required and must not be nil. It is used for network communication.
//
// Return statuses:
@ -80,7 +80,7 @@ func (x ResSessionCreate) PublicKey() []byte {
func (c *Client) SessionCreate(ctx context.Context, prm PrmSessionCreate) (*ResSessionCreate, error) {
// check context
if ctx == nil {
panic(panicMsgMissingContext)
return nil, errorMissingContext
}
ownerKey := c.prm.key.PublicKey

View file

@ -28,7 +28,6 @@ FILTER City EQ SPB AND SSD EQ true OR City EQ SPB AND Rating GE 5 AS SPBSSD`,
var p PlacementPolicy
for _, testCase := range testCases {
require.NoError(t, p.DecodeString(testCase))
var b strings.Builder

View file

@ -4,6 +4,7 @@ import (
"context"
"crypto/ecdsa"
"errors"
"go.uber.org/zap"
fyrchik commented 2023-02-17 08:52:16 +00:00 (Migrated from github.com)
Review

Unrelated to this commit, could also merge this with the next line.

Unrelated to this commit, could also merge this with the next line.
acid-ant commented 2023-02-17 14:10:31 +00:00 (Migrated from github.com)
Review

Reverted. Moved to another commit.

Reverted. Moved to another commit.
sessionv2 "github.com/TrueCloudLab/frostfs-api-go/v2/session"

View file

@ -1664,14 +1664,7 @@ func (p *Pool) log(level zapcore.Level, msg string, fields ...zap.Field) {
return
}
switch level {
case zap.DebugLevel:
p.logger.Debug(msg, fields...)
case zap.WarnLevel:
p.logger.Warn(msg, fields...)
case zap.ErrorLevel:
p.logger.Error(msg, fields...)
}
p.logger.Log(level, msg, fields...)
}
func fillDefaultInitParams(params *InitParameters, cache *sessionCache) {