[#1561] object: Return OUT_OF_RANGE status

Replace `ErrRangeOutOfBounds` error from `pkg/core/object` package with
`ObjectOutOfRange` from `apistatus` package. That error is returned by
storage node's server as NeoFS API statuses.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2022-06-29 20:33:48 +03:00 committed by fyrchik
parent ccba07fe19
commit 9f7a22e2aa
11 changed files with 46 additions and 27 deletions

View file

@ -1,7 +0,0 @@
package object
import "errors"
// ErrRangeOutOfBounds is a basic error of violation of the boundaries of the
// payload of an object.
var ErrRangeOutOfBounds = errors.New("payload range is out of bounds")

View file

@ -10,7 +10,6 @@ import (
"github.com/hashicorp/golang-lru/simplelru" "github.com/hashicorp/golang-lru/simplelru"
"github.com/nspcc-dev/hrw" "github.com/nspcc-dev/hrw"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log" storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status" apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
@ -331,7 +330,7 @@ func (b *blobovniczas) getRange(prm GetRangeSmallPrm) (res GetRangeSmallRes, err
res, err = b.getRangeFromLevel(prm, p, !ok) res, err = b.getRangeFromLevel(prm, p, !ok)
if err != nil { if err != nil {
outOfBounds := errors.Is(err, object.ErrRangeOutOfBounds) outOfBounds := isErrOutOfRange(err)
if !blobovnicza.IsErrNotFound(err) && !outOfBounds { if !blobovnicza.IsErrNotFound(err) && !outOfBounds {
b.log.Debug("could not get object from level", b.log.Debug("could not get object from level",
zap.String("level", p), zap.String("level", p),
@ -498,7 +497,7 @@ func (b *blobovniczas) getRangeFromLevel(prm GetRangeSmallPrm, blzPath string, t
res, err := b.getObjectRange(v.(*blobovnicza.Blobovnicza), prm) res, err := b.getObjectRange(v.(*blobovnicza.Blobovnicza), prm)
switch { switch {
case err == nil, case err == nil,
errors.Is(err, object.ErrRangeOutOfBounds): isErrOutOfRange(err):
return res, err return res, err
default: default:
if !blobovnicza.IsErrNotFound(err) { if !blobovnicza.IsErrNotFound(err) {
@ -523,7 +522,7 @@ func (b *blobovniczas) getRangeFromLevel(prm GetRangeSmallPrm, blzPath string, t
res, err := b.getObjectRange(active.blz, prm) res, err := b.getObjectRange(active.blz, prm)
switch { switch {
case err == nil, case err == nil,
errors.Is(err, object.ErrRangeOutOfBounds): isErrOutOfRange(err):
return res, err return res, err
default: default:
if !blobovnicza.IsErrNotFound(err) { if !blobovnicza.IsErrNotFound(err) {
@ -630,7 +629,9 @@ func (b *blobovniczas) getObjectRange(blz *blobovnicza.Blobovnicza, prm GetRange
payload := obj.Payload() payload := obj.Payload()
if uint64(len(payload)) < to { if uint64(len(payload)) < to {
return GetRangeSmallRes{}, object.ErrRangeOutOfBounds var errOutOfRange apistatus.ObjectOutOfRange
return GetRangeSmallRes{}, errOutOfRange
} }
return GetRangeSmallRes{ return GetRangeSmallRes{

View file

@ -0,0 +1,11 @@
package blobstor
import (
"errors"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
)
func isErrOutOfRange(err error) bool {
return errors.As(err, new(apistatus.ObjectOutOfRange))
}

View file

@ -4,7 +4,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status" apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object" objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
@ -56,7 +55,9 @@ func (b *BlobStor) GetRangeBig(prm GetRangeBigPrm) (GetRangeBigRes, error) {
ln, off := prm.rng.GetLength(), prm.rng.GetOffset() ln, off := prm.rng.GetLength(), prm.rng.GetOffset()
if pLen := uint64(len(payload)); pLen < ln+off { if pLen := uint64(len(payload)); pLen < ln+off {
return GetRangeBigRes{}, object.ErrRangeOutOfBounds var errOutOfRange apistatus.ObjectOutOfRange
return GetRangeBigRes{}, errOutOfRange
} }
return GetRangeBigRes{ return GetRangeBigRes{

View file

@ -11,6 +11,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test" cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object" objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -184,7 +185,7 @@ func TestBlobstorFailback(t *testing.T) {
require.Equal(t, objs[i].Payload()[1:11], rngRes.Object().Payload()) require.Equal(t, objs[i].Payload()[1:11], rngRes.Object().Payload())
_, err = e.GetRange(RngPrm{addr: addr, off: errSmallSize + 10, ln: 1}) _, err = e.GetRange(RngPrm{addr: addr, off: errSmallSize + 10, ln: 1})
require.ErrorIs(t, err, object.ErrRangeOutOfBounds) require.ErrorAs(t, err, &apistatus.ObjectOutOfRange{})
} }
checkShardState(t, e, id[0], 4, shard.ModeDegraded) checkShardState(t, e, id[0], 4, shard.ModeDegraded)

View file

@ -3,7 +3,6 @@ package engine
import ( import (
"errors" "errors"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status" apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
@ -121,7 +120,7 @@ func (e *StorageEngine) getRange(prm RngPrm) (RngRes, error) {
return false return false
case case
shard.IsErrRemoved(err), shard.IsErrRemoved(err),
errors.Is(err, object.ErrRangeOutOfBounds): shard.IsErrOutOfRange(err):
outError = err outError = err
return true // stop, return it back return true // stop, return it back
@ -152,8 +151,10 @@ func (e *StorageEngine) getRange(prm RngPrm) (RngRes, error) {
e.iterateOverSortedShards(prm.addr, func(_ int, sh hashedShard) (stop bool) { e.iterateOverSortedShards(prm.addr, func(_ int, sh hashedShard) (stop bool) {
res, err := sh.GetRange(shPrm) res, err := sh.GetRange(shPrm)
if errors.Is(err, object.ErrRangeOutOfBounds) { if shard.IsErrOutOfRange(err) {
outError = object.ErrRangeOutOfBounds var errOutOfRange apistatus.ObjectOutOfRange
outError = errOutOfRange
return true return true
} }
obj = res.Object() obj = res.Object()

View file

@ -17,3 +17,9 @@ func IsErrNotFound(err error) bool {
func IsErrRemoved(err error) bool { func IsErrRemoved(err error) bool {
return errors.As(err, new(apistatus.ObjectAlreadyRemoved)) return errors.As(err, new(apistatus.ObjectAlreadyRemoved))
} }
// IsErrOutOfRange checks if an error returned by Shard GetRange method
// corresponds to exceeding the object bounds.
func IsErrOutOfRange(err error) bool {
return errors.As(err, new(apistatus.ObjectOutOfRange))
}

View file

@ -1,10 +1,8 @@
package shard package shard
import ( import (
"errors"
"fmt" "fmt"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
@ -129,7 +127,7 @@ func (s *Shard) fetchObjectData(addr oid.Address, skipMeta bool, big, small stor
if skipMeta || err != nil { if skipMeta || err != nil {
res, err = small(s.blobStor, nil) res, err = small(s.blobStor, nil)
if err == nil || errors.Is(err, object.ErrRangeOutOfBounds) { if err == nil || IsErrOutOfRange(err) {
return res, false, err return res, false, err
} }
res, err = big(s.blobStor, nil) res, err = big(s.blobStor, nil)

View file

@ -1,7 +1,7 @@
package getsvc package getsvc
import ( import (
"github.com/nspcc-dev/neofs-node/pkg/core/object" apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object" objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id" oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"go.uber.org/zap" "go.uber.org/zap"
@ -93,8 +93,11 @@ func (exec *execCtx) initFromChild(obj oid.ID) (prev *oid.ID, children []oid.ID)
parSize := par.PayloadSize() parSize := par.PayloadSize()
if seekOff+seekLen > parSize { if seekOff+seekLen > parSize {
var errOutOfRange apistatus.ObjectOutOfRange
exec.err = errOutOfRange
exec.status = statusOutOfRange exec.status = statusOutOfRange
exec.err = object.ErrRangeOutOfBounds
return return
} }

View file

@ -3,7 +3,6 @@ package getsvc
import ( import (
"errors" "errors"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status" apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object" objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
"go.uber.org/zap" "go.uber.org/zap"
@ -16,6 +15,7 @@ func (exec *execCtx) executeLocal() {
var errSplitInfo *objectSDK.SplitInfoError var errSplitInfo *objectSDK.SplitInfoError
var errRemoved apistatus.ObjectAlreadyRemoved var errRemoved apistatus.ObjectAlreadyRemoved
var errOutOfRange apistatus.ObjectOutOfRange
switch { switch {
default: default:
@ -36,8 +36,8 @@ func (exec *execCtx) executeLocal() {
exec.status = statusVIRTUAL exec.status = statusVIRTUAL
mergeSplitInfo(exec.splitInfo(), errSplitInfo.SplitInfo()) mergeSplitInfo(exec.splitInfo(), errSplitInfo.SplitInfo())
exec.err = objectSDK.NewSplitInfoError(exec.infoSplit) exec.err = objectSDK.NewSplitInfoError(exec.infoSplit)
case errors.Is(err, object.ErrRangeOutOfBounds): case errors.As(err, &errOutOfRange):
exec.status = statusOutOfRange exec.status = statusOutOfRange
exec.err = object.ErrRangeOutOfBounds exec.err = errOutOfRange
} }
} }

View file

@ -22,6 +22,7 @@ func (exec *execCtx) processNode(ctx context.Context, info client.NodeInfo) bool
var errSplitInfo *objectSDK.SplitInfoError var errSplitInfo *objectSDK.SplitInfoError
var errRemoved *apistatus.ObjectAlreadyRemoved var errRemoved *apistatus.ObjectAlreadyRemoved
var errOutOfRange *apistatus.ObjectOutOfRange
switch { switch {
default: default:
@ -47,6 +48,9 @@ func (exec *execCtx) processNode(ctx context.Context, info client.NodeInfo) bool
case errors.As(err, &errRemoved): case errors.As(err, &errRemoved):
exec.status = statusINHUMED exec.status = statusINHUMED
exec.err = errRemoved exec.err = errRemoved
case errors.As(err, &errOutOfRange):
exec.status = statusOutOfRange
exec.err = errOutOfRange
case errors.As(err, &errSplitInfo): case errors.As(err, &errSplitInfo):
exec.status = statusVIRTUAL exec.status = statusVIRTUAL
mergeSplitInfo(exec.splitInfo(), errSplitInfo.SplitInfo()) mergeSplitInfo(exec.splitInfo(), errSplitInfo.SplitInfo())