satellite/metabase: better error message while move
Before this change we were returning full DB error message. That can be very confusing for end user. This change is translating error message into more user frindly version and fixes also DRPC error status code. Fixes https://github.com/storj/team-metainfo/issues/76 Change-Id: I29b06ab4ba50a0d14db7a822a2906d95d65ab524
This commit is contained in:
parent
bc161794fc
commit
2e31ef3f29
@ -192,7 +192,7 @@ func (db *DB) BeginObjectExactVersion(ctx context.Context, opts BeginObjectExact
|
||||
)
|
||||
if err != nil {
|
||||
if code := pgerrcode.FromError(err); code == pgxerrcode.UniqueViolation {
|
||||
return Object{}, ErrConflict.New("object already exists")
|
||||
return Object{}, Error.Wrap(ErrObjectAlreadyExists.New(""))
|
||||
}
|
||||
return Object{}, Error.New("unable to insert object: %w", err)
|
||||
}
|
||||
|
@ -494,8 +494,7 @@ func TestBeginObjectExactVersion(t *testing.T) {
|
||||
Encryption: metabasetest.DefaultEncryption,
|
||||
},
|
||||
Version: -1,
|
||||
ErrClass: &metabase.ErrConflict,
|
||||
ErrText: "object already exists",
|
||||
ErrClass: &metabase.ErrObjectAlreadyExists,
|
||||
}.Check(ctx, t, db)
|
||||
|
||||
metabasetest.Verify{
|
||||
@ -545,8 +544,7 @@ func TestBeginObjectExactVersion(t *testing.T) {
|
||||
Encryption: metabasetest.DefaultEncryption,
|
||||
},
|
||||
Version: -1,
|
||||
ErrClass: &metabase.ErrConflict,
|
||||
ErrText: "object already exists",
|
||||
ErrClass: &metabase.ErrObjectAlreadyExists,
|
||||
}.Check(ctx, t, db)
|
||||
|
||||
metabasetest.Verify{
|
||||
|
@ -19,6 +19,9 @@ import (
|
||||
// Error is the default error for metabase.
|
||||
var Error = errs.Class("metabase")
|
||||
|
||||
// ErrObjectAlreadyExists is used to indicate that object already exists.
|
||||
var ErrObjectAlreadyExists = errs.Class("object already exists")
|
||||
|
||||
// Common constants for segment keys.
|
||||
const (
|
||||
Delimiter = '/'
|
||||
|
@ -8,9 +8,12 @@ import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
|
||||
pgxerrcode "github.com/jackc/pgerrcode"
|
||||
|
||||
"storj.io/common/storj"
|
||||
"storj.io/common/uuid"
|
||||
"storj.io/private/dbutil/pgutil"
|
||||
"storj.io/private/dbutil/pgutil/pgerrcode"
|
||||
"storj.io/private/dbutil/txutil"
|
||||
"storj.io/private/tagsql"
|
||||
)
|
||||
@ -167,7 +170,9 @@ func (db *DB) FinishMoveObject(ctx context.Context, opts FinishMoveObject) (err
|
||||
var segmentsCount int
|
||||
row := db.db.QueryRowContext(ctx, updateObjectsQuery, []byte(opts.NewBucket), opts.NewEncryptedObjectKey, opts.NewEncryptedMetadataKey, opts.NewEncryptedMetadataKeyNonce, opts.ProjectID, []byte(opts.BucketName), opts.ObjectKey, opts.Version, opts.StreamID)
|
||||
if err = row.Scan(&segmentsCount); err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if code := pgerrcode.FromError(err); code == pgxerrcode.UniqueViolation {
|
||||
return Error.Wrap(ErrObjectAlreadyExists.New(""))
|
||||
} else if errors.Is(err, sql.ErrNoRows) {
|
||||
return storj.ErrObjectNotFound.New("object not found")
|
||||
}
|
||||
return Error.New("unable to update object: %w", err)
|
||||
|
@ -190,6 +190,28 @@ func TestFinishMoveObject(t *testing.T) {
|
||||
metabasetest.Verify{}.Check(ctx, t, db)
|
||||
})
|
||||
|
||||
t.Run("object already exists", func(t *testing.T) {
|
||||
defer metabasetest.DeleteAll{}.Check(ctx, t, db)
|
||||
|
||||
moveObjStream := metabasetest.RandObjectStream()
|
||||
metabasetest.CreateObject(ctx, t, db, moveObjStream, 0)
|
||||
|
||||
conflictObjStream := metabasetest.RandObjectStream()
|
||||
conflictObjStream.ProjectID = moveObjStream.ProjectID
|
||||
metabasetest.CreateObject(ctx, t, db, conflictObjStream, 0)
|
||||
|
||||
metabasetest.FinishMoveObject{
|
||||
Opts: metabase.FinishMoveObject{
|
||||
NewBucket: conflictObjStream.BucketName,
|
||||
ObjectStream: moveObjStream,
|
||||
NewEncryptedObjectKey: []byte(conflictObjStream.ObjectKey),
|
||||
NewEncryptedMetadataKeyNonce: testrand.Nonce().Bytes(),
|
||||
NewEncryptedMetadataKey: testrand.Bytes(265),
|
||||
},
|
||||
ErrClass: &metabase.ErrObjectAlreadyExists,
|
||||
}.Check(ctx, t, db)
|
||||
})
|
||||
|
||||
t.Run("object does not exist", func(t *testing.T) {
|
||||
defer metabasetest.DeleteAll{}.Check(ctx, t, db)
|
||||
|
||||
|
@ -278,6 +278,8 @@ func (endpoint *Endpoint) convertMetabaseErr(err error) error {
|
||||
return rpcstatus.Error(rpcstatus.NotFound, err.Error())
|
||||
case metabase.ErrInvalidRequest.Has(err):
|
||||
return rpcstatus.Error(rpcstatus.InvalidArgument, err.Error())
|
||||
case metabase.ErrObjectAlreadyExists.Has(err):
|
||||
return rpcstatus.Error(rpcstatus.AlreadyExists, err.Error())
|
||||
default:
|
||||
endpoint.log.Error("internal", zap.Error(err))
|
||||
return rpcstatus.Error(rpcstatus.Internal, err.Error())
|
||||
|
Loading…
Reference in New Issue
Block a user