handlers: overhaul entire writErrorResponse, simplify. (#1472)

This commit is contained in:
Harshavardhana 2016-05-05 20:24:29 -07:00 committed by Anand Babu (AB) Periasamy
parent ba5805e60a
commit 17868ccd7f
7 changed files with 120 additions and 317 deletions

View file

@ -108,8 +108,8 @@ const (
// Add new error codes here.
// Extended errors.
ErrInsufficientReadResources
ErrInsufficientWriteResources
ErrReadQuorum
ErrWriteQuorum
)
// error code to APIError structure, these fields carry respective
@ -190,15 +190,15 @@ var errorCodeResponse = map[APIErrorCode]APIError{
Description: "We encountered an internal error, please try again.",
HTTPStatusCode: http.StatusInternalServerError,
},
ErrInsufficientReadResources: {
Code: "InternalError",
Description: "We cannot satisfy sufficient read resources requested at this moment, please try again.",
HTTPStatusCode: http.StatusInternalServerError,
ErrReadQuorum: {
Code: "ReadQuorum",
Description: "Multiple disk failures, unable to reconstruct data.",
HTTPStatusCode: http.StatusServiceUnavailable,
},
ErrInsufficientWriteResources: {
Code: "InternalError",
Description: "We cannot satisfy sufficient write resources requested at this moment, please try again.",
HTTPStatusCode: http.StatusInternalServerError,
ErrWriteQuorum: {
Code: "WriteQuorum",
Description: "Multiple disks failures, unable to write data.",
HTTPStatusCode: http.StatusServiceUnavailable,
},
ErrInvalidAccessKeyID: {
Code: "InvalidAccessKeyID",
@ -418,6 +418,52 @@ var errorCodeResponse = map[APIErrorCode]APIError{
// Add your error structure here.
}
// toAPIErrorCode - Converts embedded errors. Convenience
// function written to handle all cases where we have known types of
// errors returned by underlying layers.
func toAPIErrorCode(err error) (apiErr APIErrorCode) {
if err == nil {
return ErrNone
}
// Verify if the underlying error is signature mismatch.
if err == errSignatureMismatch {
return ErrSignatureDoesNotMatch
}
switch err.(type) {
case StorageFull:
apiErr = ErrStorageFull
case BadDigest:
apiErr = ErrBadDigest
case IncompleteBody:
apiErr = ErrIncompleteBody
case ObjectExistsAsPrefix:
apiErr = ErrObjectExistsAsPrefix
case BucketNameInvalid:
apiErr = ErrInvalidBucketName
case BucketNotFound:
apiErr = ErrNoSuchBucket
case BucketNotEmpty:
apiErr = ErrBucketNotEmpty
case BucketExists:
apiErr = ErrBucketAlreadyOwnedByYou
case ObjectNotFound:
apiErr = ErrNoSuchKey
case ObjectNameInvalid:
apiErr = ErrNoSuchKey
case InvalidUploadID:
apiErr = ErrNoSuchUpload
case InvalidPart:
apiErr = ErrInvalidPart
case InsufficientWriteQuorum:
apiErr = ErrWriteQuorum
case InsufficientReadQuorum:
apiErr = ErrReadQuorum
default:
apiErr = ErrInternalError
}
return apiErr
}
// getAPIError provides API Error for input API error code.
func getAPIError(code APIErrorCode) APIError {
return errorCodeResponse[code]

View file

@ -118,14 +118,7 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *
if _, err := api.ObjectAPI.GetBucketInfo(bucket); err != nil {
errorIf(err, "GetBucketInfo failed.", nil)
switch err.(type) {
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
@ -196,12 +189,7 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter,
listMultipartsInfo, err := api.ObjectAPI.ListMultipartUploads(bucket, prefix, keyMarker, uploadIDMarker, delimiter, maxUploads)
if err != nil {
errorIf(err, "ListMultipartUploads failed.", nil)
switch err.(type) {
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
// generate response
@ -281,16 +269,7 @@ func (api objectAPIHandlers) ListObjectsHandler(w http.ResponseWriter, r *http.R
return
}
errorIf(err, "ListObjects failed.", nil)
switch err.(type) {
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case ObjectNameInvalid:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
}
// ListBucketsHandler - GET Service
@ -344,13 +323,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
return
}
errorIf(err, "ListBuckets failed.", nil)
switch err.(type) {
case StorageInsufficientReadResources:
writeErrorResponse(w, r, ErrInsufficientReadResources, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
}
// DeleteMultipleObjectsHandler - deletes multiple objects.
@ -419,38 +392,11 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
})
} else {
errorIf(err, "DeleteObject failed.", nil)
switch err.(type) {
case BucketNameInvalid:
deleteErrors = append(deleteErrors, DeleteError{
Code: errorCodeResponse[ErrInvalidBucketName].Code,
Message: errorCodeResponse[ErrInvalidBucketName].Description,
Key: object.ObjectName,
})
case BucketNotFound:
deleteErrors = append(deleteErrors, DeleteError{
Code: errorCodeResponse[ErrNoSuchBucket].Code,
Message: errorCodeResponse[ErrNoSuchBucket].Description,
Key: object.ObjectName,
})
case ObjectNotFound:
deleteErrors = append(deleteErrors, DeleteError{
Code: errorCodeResponse[ErrNoSuchKey].Code,
Message: errorCodeResponse[ErrNoSuchKey].Description,
Key: object.ObjectName,
})
case ObjectNameInvalid:
deleteErrors = append(deleteErrors, DeleteError{
Code: errorCodeResponse[ErrNoSuchKey].Code,
Message: errorCodeResponse[ErrNoSuchKey].Description,
Key: object.ObjectName,
})
default:
deleteErrors = append(deleteErrors, DeleteError{
Code: errorCodeResponse[ErrInternalError].Code,
Message: errorCodeResponse[ErrInternalError].Description,
Key: object.ObjectName,
})
}
deleteErrors = append(deleteErrors, DeleteError{
Code: errorCodeResponse[toAPIErrorCode(err)].Code,
Message: errorCodeResponse[toAPIErrorCode(err)].Description,
Key: object.ObjectName,
})
}
}
// Generate response
@ -466,7 +412,6 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
// ----------
// This implementation of the PUT operation creates a new bucket for authenticated request
func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bucket := vars["bucket"]
@ -495,14 +440,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req
err := api.ObjectAPI.MakeBucket(bucket)
if err != nil {
errorIf(err, "MakeBucket failed.", nil)
switch err.(type) {
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BucketExists:
writeErrorResponse(w, r, ErrBucketAlreadyOwnedByYou, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
// Make sure to add Location information here only for bucket
@ -573,20 +511,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
md5Sum, err := api.ObjectAPI.PutObject(bucket, object, -1, fileBody, nil)
if err != nil {
errorIf(err, "PutObject failed.", nil)
switch err.(type) {
case StorageFull:
writeErrorResponse(w, r, ErrStorageFull, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BadDigest:
writeErrorResponse(w, r, ErrBadDigest, r.URL.Path)
case IncompleteBody:
writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
if md5Sum != "" {
@ -632,16 +557,7 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re
if _, err := api.ObjectAPI.GetBucketInfo(bucket); err != nil {
errorIf(err, "GetBucketInfo failed.", nil)
switch err.(type) {
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case StorageInsufficientReadResources:
writeErrorResponse(w, r, ErrInsufficientReadResources, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
writeSuccessResponse(w, nil)
@ -666,14 +582,7 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.
if err := api.ObjectAPI.DeleteBucket(bucket); err != nil {
errorIf(err, "DeleteBucket failed.", nil)
switch err.(type) {
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case BucketNotEmpty:
writeErrorResponse(w, r, ErrBucketNotEmpty, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}

View file

@ -41,9 +41,9 @@ func toObjectErr(err error, params ...string) error {
case errDiskFull:
return StorageFull{}
case errReadQuorum:
return StorageInsufficientReadResources{}
return InsufficientReadQuorum{}
case errWriteQuorum:
return StorageInsufficientWriteResources{}
return InsufficientWriteQuorum{}
case errIsNotRegular, errFileAccessDenied:
if len(params) >= 2 {
return ObjectExistsAsPrefix{
@ -71,18 +71,18 @@ func (e StorageFull) Error() string {
return "Storage reached its minimum free disk threshold."
}
// StorageInsufficientReadResources storage cannot satisfy quorum for read operation.
type StorageInsufficientReadResources struct{}
// InsufficientReadQuorum storage cannot satisfy quorum for read operation.
type InsufficientReadQuorum struct{}
func (e StorageInsufficientReadResources) Error() string {
func (e InsufficientReadQuorum) Error() string {
return "Storage resources are insufficient for the read operation."
}
// StorageInsufficientWriteResources storage cannot satisfy quorum for write operation.
type StorageInsufficientWriteResources struct{}
// InsufficientWriteQuorum storage cannot satisfy quorum for write operation.
type InsufficientWriteQuorum struct{}
func (e StorageInsufficientWriteResources) Error() string {
return "Stroage resources are insufficient for the write operation."
func (e InsufficientWriteQuorum) Error() string {
return "Storage resources are insufficient for the write operation."
}
// GenericError - generic object layer error.

View file

@ -65,7 +65,6 @@ func errAllowableObjectNotFound(bucket string, r *http.Request) APIErrorCode {
return ErrAccessDenied
}
}
return ErrNoSuchKey
}
@ -100,18 +99,11 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
objInfo, err := api.ObjectAPI.GetObjectInfo(bucket, object)
if err != nil {
errorIf(err, "GetObjectInfo failed.", nil)
switch err.(type) {
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case ObjectNotFound:
writeErrorResponse(w, r, errAllowableObjectNotFound(bucket, r), r.URL.Path)
case ObjectNameInvalid:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
apiErr := toAPIErrorCode(err)
if apiErr == ErrNoSuchKey {
apiErr = errAllowableObjectNotFound(bucket, r)
}
writeErrorResponse(w, r, apiErr, r.URL.Path)
return
}
@ -136,15 +128,12 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
startOffset := hrange.start
readCloser, err := api.ObjectAPI.GetObject(bucket, object, startOffset)
if err != nil {
switch err.(type) {
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case ObjectNotFound:
writeErrorResponse(w, r, errAllowableObjectNotFound(bucket, r), r.URL.Path)
default:
errorIf(err, "GetObject failed.", nil)
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
errorIf(err, "GetObject failed.", nil)
apiErr := toAPIErrorCode(err)
if apiErr == ErrNoSuchKey {
apiErr = errAllowableObjectNotFound(bucket, r)
}
writeErrorResponse(w, r, apiErr, r.URL.Path)
return
}
defer readCloser.Close() // Close after this handler returns.
@ -294,18 +283,11 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re
objInfo, err := api.ObjectAPI.GetObjectInfo(bucket, object)
if err != nil {
errorIf(err, "GetObjectInfo failed.", nil)
switch err.(type) {
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case ObjectNotFound:
writeErrorResponse(w, r, errAllowableObjectNotFound(bucket, r), r.URL.Path)
case ObjectNameInvalid:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
apiErr := toAPIErrorCode(err)
if apiErr == ErrNoSuchKey {
apiErr = errAllowableObjectNotFound(bucket, r)
}
writeErrorResponse(w, r, apiErr, r.URL.Path)
return
}
@ -387,18 +369,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
objInfo, err := api.ObjectAPI.GetObjectInfo(sourceBucket, sourceObject)
if err != nil {
errorIf(err, "GetObjectInfo failed.", nil)
switch err.(type) {
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, objectSource)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, objectSource)
case ObjectNotFound:
writeErrorResponse(w, r, ErrNoSuchKey, objectSource)
case ObjectNameInvalid:
writeErrorResponse(w, r, ErrNoSuchKey, objectSource)
default:
writeErrorResponse(w, r, ErrInternalError, objectSource)
}
writeErrorResponse(w, r, toAPIErrorCode(err), objectSource)
return
}
// Verify before writing.
@ -437,14 +408,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
readCloser, err := api.ObjectAPI.GetObject(sourceBucket, sourceObject, startOffset)
if err != nil {
errorIf(err, "Reading "+objectSource+" failed.", nil)
switch err.(type) {
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, objectSource)
case ObjectNotFound:
writeErrorResponse(w, r, ErrNoSuchKey, objectSource)
default:
writeErrorResponse(w, r, ErrInternalError, objectSource)
}
writeErrorResponse(w, r, toAPIErrorCode(err), objectSource)
return
}
// Size of object.
@ -458,29 +422,14 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
md5Sum, err := api.ObjectAPI.PutObject(bucket, object, size, readCloser, metadata)
if err != nil {
errorIf(err, "PutObject failed.", nil)
switch err.(type) {
case StorageFull:
writeErrorResponse(w, r, ErrStorageFull, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BadDigest:
writeErrorResponse(w, r, ErrBadDigest, r.URL.Path)
case IncompleteBody:
writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path)
case ObjectExistsAsPrefix:
writeErrorResponse(w, r, ErrObjectExistsAsPrefix, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
objInfo, err = api.ObjectAPI.GetObjectInfo(bucket, object)
if err != nil {
errorIf(err, "GetObjectInfo failed.", nil)
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
@ -675,27 +624,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
}
if err != nil {
errorIf(err, "PutObject failed.", nil)
// Verify if the underlying error is signature mismatch.
if err == errSignatureMismatch {
writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path)
return
}
switch err.(type) {
case StorageFull:
writeErrorResponse(w, r, ErrStorageFull, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BadDigest:
writeErrorResponse(w, r, ErrBadDigest, r.URL.Path)
case IncompleteBody:
writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path)
case ObjectExistsAsPrefix:
writeErrorResponse(w, r, ErrObjectExistsAsPrefix, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
if md5Sum != "" {
@ -734,20 +663,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r
uploadID, err := api.ObjectAPI.NewMultipartUpload(bucket, object)
if err != nil {
errorIf(err, "NewMultipartUpload failed.", nil)
switch err.(type) {
case StorageFull:
writeErrorResponse(w, r, ErrStorageFull, r.URL.Path)
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case ObjectNotFound:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
case ObjectNameInvalid:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
@ -847,22 +763,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http
if err != nil {
errorIf(err, "PutObjectPart failed.", nil)
// Verify if the underlying error is signature mismatch.
if err == errSignatureMismatch {
writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path)
return
}
switch err.(type) {
case StorageFull:
writeErrorResponse(w, r, ErrStorageFull, r.URL.Path)
case InvalidUploadID:
writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path)
case BadDigest:
writeErrorResponse(w, r, ErrBadDigest, r.URL.Path)
case IncompleteBody:
writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
if partMD5 != "" {
@ -898,20 +799,7 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter,
uploadID, _, _, _ := getObjectResources(r.URL.Query())
if err := api.ObjectAPI.AbortMultipartUpload(bucket, object, uploadID); err != nil {
errorIf(err, "AbortMutlipartUpload failed.", nil)
switch err.(type) {
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case ObjectNotFound:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
case ObjectNameInvalid:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
case InvalidUploadID:
writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
writeSuccessNoContent(w)
@ -957,22 +845,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht
listPartsInfo, err := api.ObjectAPI.ListObjectParts(bucket, object, uploadID, partNumberMarker, maxParts)
if err != nil {
errorIf(err, "ListObjectParts failed.", nil)
switch err.(type) {
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case ObjectNotFound:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
case ObjectNameInvalid:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
case InvalidUploadID:
writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path)
case InvalidPart:
writeErrorResponse(w, r, ErrInvalidPart, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
response := generateListPartsResponse(listPartsInfo)
@ -1038,24 +911,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
md5Sum, err = api.ObjectAPI.CompleteMultipartUpload(bucket, object, uploadID, completeParts)
if err != nil {
errorIf(err, "CompleteMultipartUpload failed.", nil)
switch err.(type) {
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case ObjectNotFound:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
case ObjectNameInvalid:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
case InvalidUploadID:
writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path)
case InvalidPart:
writeErrorResponse(w, r, ErrInvalidPart, r.URL.Path)
case IncompleteBody:
writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
// Get object location.
@ -1096,18 +952,7 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.
}
if err := api.ObjectAPI.DeleteObject(bucket, object); err != nil {
errorIf(err, "DeleteObject failed.", nil)
switch err.(type) {
case BucketNameInvalid:
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
case BucketNotFound:
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
case ObjectNotFound:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
case ObjectNameInvalid:
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
default:
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
}
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
return
}
writeSuccessNoContent(w)

View file

@ -411,10 +411,10 @@ func writeWebErrorResponse(w http.ResponseWriter, err error) {
apiErrCode = ErrNoSuchKey
case ObjectNameInvalid:
apiErrCode = ErrNoSuchKey
case StorageInsufficientWriteResources:
apiErrCode = ErrInsufficientWriteResources
case StorageInsufficientReadResources:
apiErrCode = ErrInsufficientReadResources
case InsufficientWriteQuorum:
apiErrCode = ErrWriteQuorum
case InsufficientReadQuorum:
apiErrCode = ErrReadQuorum
default:
apiErrCode = ErrInternalError
}

View file

@ -62,13 +62,12 @@ func (xl XL) listOnlineDisks(volume, path string) (onlineDisks []StorageAPI, mda
for _, err := range errs {
if err == errFileNotFound {
notFoundCount++
// If we have errors with file not found greater than allowed read
// quorum we return err as errFileNotFound.
if notFoundCount > len(xl.storageDisks)-xl.readQuorum {
return nil, xlMetaV1{}, false, errFileNotFound
}
}
}
// If we have errors with file not found equal to the number of disks.
if notFoundCount == len(xl.storageDisks) {
return nil, xlMetaV1{}, false, errFileNotFound
}
highestVersion := int64(0)
onlineDisks = make([]StorageAPI, len(xl.storageDisks))
// List all the file versions from partsMetadata list.

View file

@ -163,13 +163,17 @@ func (xl xlObjects) GetObjectInfo(bucket, object string) (ObjectInfo, error) {
}
fi, err := xl.storage.StatFile(bucket, object)
if err != nil {
info, err := getMultipartObjectInfo(xl.storage, bucket, object)
if err != nil {
return ObjectInfo{}, toObjectErr(err, bucket, object)
if err == errFileNotFound {
var info MultipartObjectInfo
info, err = getMultipartObjectInfo(xl.storage, bucket, object)
if err != nil {
return ObjectInfo{}, toObjectErr(err, bucket, object)
}
fi.Size = info.Size
fi.ModTime = info.ModTime
fi.MD5Sum = info.MD5Sum
}
fi.Size = info.Size
fi.ModTime = info.ModTime
fi.MD5Sum = info.MD5Sum
return ObjectInfo{}, toObjectErr(err, bucket, object)
}
contentType := "application/octet-stream"
if objectExt := filepath.Ext(object); objectExt != "" {