mirror of
https://github.com/minio/minio.git
synced 2025-04-24 04:10:43 -04:00
Fix error returned by HealObject in some cases (#11906)
The background healing can return NoSuchUpload error, the reason is that healing code can return errFileNotFound with three parameters. Simplify the code by returning exact errUploadNotFound error in multipart code. Also ensure that a typed error is always returned whatever the number of parameters because it is better than showing internal error.
This commit is contained in:
parent
91eb1fe2ef
commit
8d5456c15a
@ -44,7 +44,13 @@ func (er erasureObjects) getMultipartSHADir(bucket, object string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// checkUploadIDExists - verify if a given uploadID exists and is valid.
|
// checkUploadIDExists - verify if a given uploadID exists and is valid.
|
||||||
func (er erasureObjects) checkUploadIDExists(ctx context.Context, bucket, object, uploadID string) error {
|
func (er erasureObjects) checkUploadIDExists(ctx context.Context, bucket, object, uploadID string) (err error) {
|
||||||
|
defer func() {
|
||||||
|
if err == errFileNotFound {
|
||||||
|
err = errUploadIDNotFound
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
disks := er.getDisks()
|
disks := er.getDisks()
|
||||||
|
|
||||||
// Read metadata associated with the object from all disks.
|
// Read metadata associated with the object from all disks.
|
||||||
@ -56,7 +62,7 @@ func (er erasureObjects) checkUploadIDExists(ctx context.Context, bucket, object
|
|||||||
}
|
}
|
||||||
|
|
||||||
if reducedErr := reduceReadQuorumErrs(ctx, errs, objectOpIgnoredErrs, readQuorum); reducedErr != nil {
|
if reducedErr := reduceReadQuorumErrs(ctx, errs, objectOpIgnoredErrs, readQuorum); reducedErr != nil {
|
||||||
return toObjectErr(reducedErr, bucket, object)
|
return reducedErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// List all online disks.
|
// List all online disks.
|
||||||
|
@ -22,139 +22,153 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Converts underlying storage error. Convenience function written to
|
// Converts underlying storage error. Convenience function written to
|
||||||
// handle all cases where we have known types of errors returned by
|
// handle all cases where we have known types of errors returned by
|
||||||
// underlying storage layer.
|
// underlying storage layer.
|
||||||
func toObjectErr(err error, params ...string) error {
|
func toObjectErr(err error, params ...string) error {
|
||||||
if len(params) > 1 {
|
|
||||||
if HasSuffix(params[1], globalDirSuffix) {
|
|
||||||
params[1] = strings.TrimSuffix(params[1], globalDirSuffix) + slashSeparator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch err {
|
switch err {
|
||||||
case errVolumeNotFound:
|
case errVolumeNotFound:
|
||||||
|
apiErr := BucketNotFound{}
|
||||||
if len(params) >= 1 {
|
if len(params) >= 1 {
|
||||||
err = BucketNotFound{Bucket: params[0]}
|
apiErr.Bucket = params[0]
|
||||||
}
|
}
|
||||||
|
return apiErr
|
||||||
case errVolumeNotEmpty:
|
case errVolumeNotEmpty:
|
||||||
|
apiErr := BucketNotEmpty{}
|
||||||
if len(params) >= 1 {
|
if len(params) >= 1 {
|
||||||
err = BucketNotEmpty{Bucket: params[0]}
|
apiErr.Bucket = params[0]
|
||||||
}
|
}
|
||||||
|
return apiErr
|
||||||
case errVolumeExists:
|
case errVolumeExists:
|
||||||
|
apiErr := BucketExists{}
|
||||||
if len(params) >= 1 {
|
if len(params) >= 1 {
|
||||||
err = BucketExists{Bucket: params[0]}
|
apiErr.Bucket = params[0]
|
||||||
}
|
}
|
||||||
|
return apiErr
|
||||||
case errDiskFull:
|
case errDiskFull:
|
||||||
err = StorageFull{}
|
return StorageFull{}
|
||||||
case errTooManyOpenFiles:
|
case errTooManyOpenFiles:
|
||||||
err = SlowDown{}
|
return SlowDown{}
|
||||||
case errFileAccessDenied:
|
case errFileAccessDenied:
|
||||||
if len(params) >= 2 {
|
apiErr := PrefixAccessDenied{}
|
||||||
err = PrefixAccessDenied{
|
if len(params) >= 1 {
|
||||||
Bucket: params[0],
|
apiErr.Bucket = params[0]
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
case errFileParentIsFile:
|
case errFileParentIsFile:
|
||||||
if len(params) >= 2 {
|
apiErr := ParentIsObject{}
|
||||||
err = ParentIsObject{
|
if len(params) >= 1 {
|
||||||
Bucket: params[0],
|
apiErr.Bucket = params[0]
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
case errIsNotRegular:
|
case errIsNotRegular:
|
||||||
if len(params) >= 2 {
|
apiErr := ObjectExistsAsDirectory{}
|
||||||
err = ObjectExistsAsDirectory{
|
if len(params) >= 1 {
|
||||||
Bucket: params[0],
|
apiErr.Bucket = params[0]
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
case errFileVersionNotFound:
|
case errFileVersionNotFound:
|
||||||
switch len(params) {
|
apiErr := VersionNotFound{}
|
||||||
case 2:
|
if len(params) >= 1 {
|
||||||
err = VersionNotFound{
|
apiErr.Bucket = params[0]
|
||||||
Bucket: params[0],
|
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
err = VersionNotFound{
|
|
||||||
Bucket: params[0],
|
|
||||||
Object: params[1],
|
|
||||||
VersionID: params[2],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
if len(params) >= 3 {
|
||||||
|
apiErr.VersionID = params[2]
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
case errMethodNotAllowed:
|
case errMethodNotAllowed:
|
||||||
switch len(params) {
|
apiErr := MethodNotAllowed{}
|
||||||
case 2:
|
if len(params) >= 1 {
|
||||||
err = MethodNotAllowed{
|
apiErr.Bucket = params[0]
|
||||||
Bucket: params[0],
|
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
case errFileNotFound:
|
case errFileNotFound:
|
||||||
switch len(params) {
|
apiErr := ObjectNotFound{}
|
||||||
case 2:
|
if len(params) >= 1 {
|
||||||
err = ObjectNotFound{
|
apiErr.Bucket = params[0]
|
||||||
Bucket: params[0],
|
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
err = InvalidUploadID{
|
|
||||||
Bucket: params[0],
|
|
||||||
Object: params[1],
|
|
||||||
UploadID: params[2],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
|
case errUploadIDNotFound:
|
||||||
|
apiErr := InvalidUploadID{}
|
||||||
|
if len(params) >= 1 {
|
||||||
|
apiErr.Bucket = params[0]
|
||||||
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
if len(params) >= 3 {
|
||||||
|
apiErr.UploadID = params[2]
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
case errFileNameTooLong:
|
case errFileNameTooLong:
|
||||||
if len(params) >= 2 {
|
apiErr := ObjectNameInvalid{}
|
||||||
err = ObjectNameInvalid{
|
if len(params) >= 1 {
|
||||||
Bucket: params[0],
|
apiErr.Bucket = params[0]
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
case errDataTooLarge:
|
case errDataTooLarge:
|
||||||
if len(params) >= 2 {
|
apiErr := ObjectTooLarge{}
|
||||||
err = ObjectTooLarge{
|
if len(params) >= 1 {
|
||||||
Bucket: params[0],
|
apiErr.Bucket = params[0]
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
case errDataTooSmall:
|
case errDataTooSmall:
|
||||||
|
apiErr := ObjectTooSmall{}
|
||||||
|
if len(params) >= 1 {
|
||||||
|
apiErr.Bucket = params[0]
|
||||||
|
}
|
||||||
if len(params) >= 2 {
|
if len(params) >= 2 {
|
||||||
err = ObjectTooSmall{
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
Bucket: params[0],
|
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return apiErr
|
||||||
case errErasureReadQuorum:
|
case errErasureReadQuorum:
|
||||||
if len(params) == 1 {
|
apiErr := InsufficientReadQuorum{}
|
||||||
err = InsufficientReadQuorum{
|
if len(params) >= 1 {
|
||||||
Bucket: params[0],
|
apiErr.Bucket = params[0]
|
||||||
}
|
|
||||||
} else if len(params) >= 2 {
|
|
||||||
err = InsufficientReadQuorum{
|
|
||||||
Bucket: params[0],
|
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
case errErasureWriteQuorum:
|
case errErasureWriteQuorum:
|
||||||
if len(params) == 1 {
|
apiErr := InsufficientWriteQuorum{}
|
||||||
err = InsufficientWriteQuorum{
|
if len(params) >= 1 {
|
||||||
Bucket: params[0],
|
apiErr.Bucket = params[0]
|
||||||
}
|
|
||||||
} else if len(params) >= 2 {
|
|
||||||
err = InsufficientWriteQuorum{
|
|
||||||
Bucket: params[0],
|
|
||||||
Object: params[1],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if len(params) >= 2 {
|
||||||
|
apiErr.Object = decodeDirObject(params[1])
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
case io.ErrUnexpectedEOF, io.ErrShortWrite:
|
case io.ErrUnexpectedEOF, io.ErrShortWrite:
|
||||||
err = IncompleteBody{}
|
return IncompleteBody{}
|
||||||
case context.Canceled, context.DeadlineExceeded:
|
case context.Canceled, context.DeadlineExceeded:
|
||||||
err = IncompleteBody{}
|
return IncompleteBody{}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -98,3 +98,6 @@ var errAccessDenied = errors.New("Do not have enough permissions to access this
|
|||||||
|
|
||||||
// error returned when object is locked.
|
// error returned when object is locked.
|
||||||
var errLockedObject = errors.New("Object is WORM protected and cannot be overwritten or deleted")
|
var errLockedObject = errors.New("Object is WORM protected and cannot be overwritten or deleted")
|
||||||
|
|
||||||
|
// error returned when upload id not found
|
||||||
|
var errUploadIDNotFound = errors.New("Specified Upload ID is not found")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user