github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/object-api-errors.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"context"
    22  	"errors"
    23  	"fmt"
    24  	"io"
    25  )
    26  
    27  // Converts underlying storage error. Convenience function written to
    28  // handle all cases where we have known types of errors returned by
    29  // underlying storage layer.
    30  func toObjectErr(err error, params ...string) error {
    31  	if err == nil {
    32  		return nil
    33  	}
    34  
    35  	// Unwarp the error first
    36  	err = unwrapAll(err)
    37  
    38  	if err == context.Canceled {
    39  		return context.Canceled
    40  	}
    41  
    42  	switch err.Error() {
    43  	case errVolumeNotFound.Error():
    44  		apiErr := BucketNotFound{}
    45  		if len(params) >= 1 {
    46  			apiErr.Bucket = params[0]
    47  		}
    48  		return apiErr
    49  	case errVolumeNotEmpty.Error():
    50  		apiErr := BucketNotEmpty{}
    51  		if len(params) >= 1 {
    52  			apiErr.Bucket = params[0]
    53  		}
    54  		return apiErr
    55  	case errVolumeExists.Error():
    56  		apiErr := BucketExists{}
    57  		if len(params) >= 1 {
    58  			apiErr.Bucket = params[0]
    59  		}
    60  		return apiErr
    61  	case errDiskFull.Error():
    62  		return StorageFull{}
    63  	case errTooManyOpenFiles.Error():
    64  		return SlowDown{}
    65  	case errFileAccessDenied.Error():
    66  		apiErr := PrefixAccessDenied{}
    67  		if len(params) >= 1 {
    68  			apiErr.Bucket = params[0]
    69  		}
    70  		if len(params) >= 2 {
    71  			apiErr.Object = decodeDirObject(params[1])
    72  		}
    73  		return apiErr
    74  	case errIsNotRegular.Error():
    75  		apiErr := ObjectExistsAsDirectory{}
    76  		if len(params) >= 1 {
    77  			apiErr.Bucket = params[0]
    78  		}
    79  		if len(params) >= 2 {
    80  			apiErr.Object = decodeDirObject(params[1])
    81  		}
    82  		return apiErr
    83  	case errFileVersionNotFound.Error():
    84  		apiErr := VersionNotFound{}
    85  		if len(params) >= 1 {
    86  			apiErr.Bucket = params[0]
    87  		}
    88  		if len(params) >= 2 {
    89  			apiErr.Object = decodeDirObject(params[1])
    90  		}
    91  		if len(params) >= 3 {
    92  			apiErr.VersionID = params[2]
    93  		}
    94  		return apiErr
    95  	case errMethodNotAllowed.Error():
    96  		apiErr := MethodNotAllowed{}
    97  		if len(params) >= 1 {
    98  			apiErr.Bucket = params[0]
    99  		}
   100  		if len(params) >= 2 {
   101  			apiErr.Object = decodeDirObject(params[1])
   102  		}
   103  		return apiErr
   104  	case errFileNotFound.Error():
   105  		apiErr := ObjectNotFound{}
   106  		if len(params) >= 1 {
   107  			apiErr.Bucket = params[0]
   108  		}
   109  		if len(params) >= 2 {
   110  			apiErr.Object = decodeDirObject(params[1])
   111  		}
   112  		return apiErr
   113  	case errUploadIDNotFound.Error():
   114  		apiErr := InvalidUploadID{}
   115  		if len(params) >= 1 {
   116  			apiErr.Bucket = params[0]
   117  		}
   118  		if len(params) >= 2 {
   119  			apiErr.Object = decodeDirObject(params[1])
   120  		}
   121  		if len(params) >= 3 {
   122  			apiErr.UploadID = params[2]
   123  		}
   124  		return apiErr
   125  	case errFileNameTooLong.Error():
   126  		apiErr := ObjectNameInvalid{}
   127  		if len(params) >= 1 {
   128  			apiErr.Bucket = params[0]
   129  		}
   130  		if len(params) >= 2 {
   131  			apiErr.Object = decodeDirObject(params[1])
   132  		}
   133  		return apiErr
   134  	case errDataTooLarge.Error():
   135  		apiErr := ObjectTooLarge{}
   136  		if len(params) >= 1 {
   137  			apiErr.Bucket = params[0]
   138  		}
   139  		if len(params) >= 2 {
   140  			apiErr.Object = decodeDirObject(params[1])
   141  		}
   142  		return apiErr
   143  	case errDataTooSmall.Error():
   144  		apiErr := ObjectTooSmall{}
   145  		if len(params) >= 1 {
   146  			apiErr.Bucket = params[0]
   147  		}
   148  		if len(params) >= 2 {
   149  			apiErr.Object = decodeDirObject(params[1])
   150  		}
   151  		return apiErr
   152  	case errErasureReadQuorum.Error():
   153  		apiErr := InsufficientReadQuorum{}
   154  		if len(params) >= 1 {
   155  			apiErr.Bucket = params[0]
   156  		}
   157  		if len(params) >= 2 {
   158  			apiErr.Object = decodeDirObject(params[1])
   159  		}
   160  		return apiErr
   161  	case errErasureWriteQuorum.Error():
   162  		apiErr := InsufficientWriteQuorum{}
   163  		if len(params) >= 1 {
   164  			apiErr.Bucket = params[0]
   165  		}
   166  		if len(params) >= 2 {
   167  			apiErr.Object = decodeDirObject(params[1])
   168  		}
   169  		return apiErr
   170  	case io.ErrUnexpectedEOF.Error(), io.ErrShortWrite.Error(), context.Canceled.Error(), context.DeadlineExceeded.Error():
   171  		apiErr := IncompleteBody{}
   172  		if len(params) >= 1 {
   173  			apiErr.Bucket = params[0]
   174  		}
   175  		if len(params) >= 2 {
   176  			apiErr.Object = decodeDirObject(params[1])
   177  		}
   178  		return apiErr
   179  	}
   180  	return err
   181  }
   182  
   183  // SignatureDoesNotMatch - when content md5 does not match with what was sent from client.
   184  type SignatureDoesNotMatch struct{}
   185  
   186  func (e SignatureDoesNotMatch) Error() string {
   187  	return "The request signature we calculated does not match the signature you provided. Check your key and signing method."
   188  }
   189  
   190  // StorageFull storage ran out of space.
   191  type StorageFull struct{}
   192  
   193  func (e StorageFull) Error() string {
   194  	return "Storage reached its minimum free drive threshold."
   195  }
   196  
   197  // SlowDown  too many file descriptors open or backend busy .
   198  type SlowDown struct{}
   199  
   200  func (e SlowDown) Error() string {
   201  	return "Please reduce your request rate"
   202  }
   203  
   204  // InsufficientReadQuorum storage cannot satisfy quorum for read operation.
   205  type InsufficientReadQuorum GenericError
   206  
   207  func (e InsufficientReadQuorum) Error() string {
   208  	return "Storage resources are insufficient for the read operation " + e.Bucket + "/" + e.Object
   209  }
   210  
   211  // Unwrap the error.
   212  func (e InsufficientReadQuorum) Unwrap() error {
   213  	return errErasureReadQuorum
   214  }
   215  
   216  // InsufficientWriteQuorum storage cannot satisfy quorum for write operation.
   217  type InsufficientWriteQuorum GenericError
   218  
   219  func (e InsufficientWriteQuorum) Error() string {
   220  	return "Storage resources are insufficient for the write operation " + e.Bucket + "/" + e.Object
   221  }
   222  
   223  // Unwrap the error.
   224  func (e InsufficientWriteQuorum) Unwrap() error {
   225  	return errErasureWriteQuorum
   226  }
   227  
   228  // GenericError - generic object layer error.
   229  type GenericError struct {
   230  	Bucket    string
   231  	Object    string
   232  	VersionID string
   233  	Err       error
   234  }
   235  
   236  // Unwrap the error to its underlying error.
   237  func (e GenericError) Unwrap() error {
   238  	return e.Err
   239  }
   240  
   241  // InvalidArgument incorrect input argument
   242  type InvalidArgument GenericError
   243  
   244  func (e InvalidArgument) Error() string {
   245  	if e.Err != nil {
   246  		return "Invalid arguments provided for " + e.Bucket + "/" + e.Object + ": (" + e.Err.Error() + ")"
   247  	}
   248  	return "Invalid arguments provided for " + e.Bucket + "/" + e.Object
   249  }
   250  
   251  // BucketNotFound bucket does not exist.
   252  type BucketNotFound GenericError
   253  
   254  func (e BucketNotFound) Error() string {
   255  	return "Bucket not found: " + e.Bucket
   256  }
   257  
   258  // BucketAlreadyExists the requested bucket name is not available.
   259  type BucketAlreadyExists GenericError
   260  
   261  func (e BucketAlreadyExists) Error() string {
   262  	return "The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again."
   263  }
   264  
   265  // BucketAlreadyOwnedByYou already owned by you.
   266  type BucketAlreadyOwnedByYou GenericError
   267  
   268  func (e BucketAlreadyOwnedByYou) Error() string {
   269  	return "Bucket already owned by you: " + e.Bucket
   270  }
   271  
   272  // BucketNotEmpty bucket is not empty.
   273  type BucketNotEmpty GenericError
   274  
   275  func (e BucketNotEmpty) Error() string {
   276  	return "Bucket not empty: " + e.Bucket
   277  }
   278  
   279  // InvalidVersionID invalid version id
   280  type InvalidVersionID GenericError
   281  
   282  func (e InvalidVersionID) Error() string {
   283  	return "Invalid version id: " + e.Bucket + "/" + e.Object + "(" + e.VersionID + ")"
   284  }
   285  
   286  // VersionNotFound version does not exist.
   287  type VersionNotFound GenericError
   288  
   289  func (e VersionNotFound) Error() string {
   290  	return "Version not found: " + e.Bucket + "/" + e.Object + "(" + e.VersionID + ")"
   291  }
   292  
   293  // ObjectNotFound object does not exist.
   294  type ObjectNotFound GenericError
   295  
   296  func (e ObjectNotFound) Error() string {
   297  	return "Object not found: " + e.Bucket + "/" + e.Object
   298  }
   299  
   300  // MethodNotAllowed on the object
   301  type MethodNotAllowed GenericError
   302  
   303  func (e MethodNotAllowed) Error() string {
   304  	return "Method not allowed: " + e.Bucket + "/" + e.Object
   305  }
   306  
   307  // ObjectLocked object is currently WORM protected.
   308  type ObjectLocked GenericError
   309  
   310  func (e ObjectLocked) Error() string {
   311  	return "Object is WORM protected and cannot be overwritten: " + e.Bucket + "/" + e.Object + "(" + e.VersionID + ")"
   312  }
   313  
   314  // ObjectAlreadyExists object already exists.
   315  type ObjectAlreadyExists GenericError
   316  
   317  func (e ObjectAlreadyExists) Error() string {
   318  	return "Object: " + e.Bucket + "/" + e.Object + " already exists"
   319  }
   320  
   321  // ObjectExistsAsDirectory object already exists as a directory.
   322  type ObjectExistsAsDirectory GenericError
   323  
   324  func (e ObjectExistsAsDirectory) Error() string {
   325  	return "Object exists on : " + e.Bucket + " as directory " + e.Object
   326  }
   327  
   328  // PrefixAccessDenied object access is denied.
   329  type PrefixAccessDenied GenericError
   330  
   331  func (e PrefixAccessDenied) Error() string {
   332  	return "Prefix access is denied: " + e.Bucket + SlashSeparator + e.Object
   333  }
   334  
   335  // BucketExists bucket exists.
   336  type BucketExists GenericError
   337  
   338  func (e BucketExists) Error() string {
   339  	return "Bucket exists: " + e.Bucket
   340  }
   341  
   342  // InvalidUploadIDKeyCombination - invalid upload id and key marker combination.
   343  type InvalidUploadIDKeyCombination struct {
   344  	UploadIDMarker, KeyMarker string
   345  }
   346  
   347  func (e InvalidUploadIDKeyCombination) Error() string {
   348  	return fmt.Sprintf("Invalid combination of uploadID marker '%s' and marker '%s'", e.UploadIDMarker, e.KeyMarker)
   349  }
   350  
   351  // BucketPolicyNotFound - no bucket policy found.
   352  type BucketPolicyNotFound GenericError
   353  
   354  func (e BucketPolicyNotFound) Error() string {
   355  	return "No bucket policy configuration found for bucket: " + e.Bucket
   356  }
   357  
   358  // BucketLifecycleNotFound - no bucket lifecycle found.
   359  type BucketLifecycleNotFound GenericError
   360  
   361  func (e BucketLifecycleNotFound) Error() string {
   362  	return "No bucket lifecycle configuration found for bucket : " + e.Bucket
   363  }
   364  
   365  // BucketSSEConfigNotFound - no bucket encryption found
   366  type BucketSSEConfigNotFound GenericError
   367  
   368  func (e BucketSSEConfigNotFound) Error() string {
   369  	return "No bucket encryption configuration found for bucket: " + e.Bucket
   370  }
   371  
   372  // BucketTaggingNotFound - no bucket tags found
   373  type BucketTaggingNotFound GenericError
   374  
   375  func (e BucketTaggingNotFound) Error() string {
   376  	return "No bucket tags found for bucket: " + e.Bucket
   377  }
   378  
   379  // BucketObjectLockConfigNotFound - no bucket object lock config found
   380  type BucketObjectLockConfigNotFound GenericError
   381  
   382  func (e BucketObjectLockConfigNotFound) Error() string {
   383  	return "No bucket object lock configuration found for bucket: " + e.Bucket
   384  }
   385  
   386  // BucketQuotaConfigNotFound - no bucket quota config found.
   387  type BucketQuotaConfigNotFound GenericError
   388  
   389  func (e BucketQuotaConfigNotFound) Error() string {
   390  	return "No quota config found for bucket : " + e.Bucket
   391  }
   392  
   393  // BucketQuotaExceeded - bucket quota exceeded.
   394  type BucketQuotaExceeded GenericError
   395  
   396  func (e BucketQuotaExceeded) Error() string {
   397  	return "Bucket quota exceeded for bucket: " + e.Bucket
   398  }
   399  
   400  // BucketReplicationConfigNotFound - no bucket replication config found
   401  type BucketReplicationConfigNotFound GenericError
   402  
   403  func (e BucketReplicationConfigNotFound) Error() string {
   404  	return "The replication configuration was not found: " + e.Bucket
   405  }
   406  
   407  // BucketRemoteDestinationNotFound bucket does not exist.
   408  type BucketRemoteDestinationNotFound GenericError
   409  
   410  func (e BucketRemoteDestinationNotFound) Error() string {
   411  	return "Destination bucket does not exist: " + e.Bucket
   412  }
   413  
   414  // BucketRemoteTargetNotFound remote target does not exist.
   415  type BucketRemoteTargetNotFound GenericError
   416  
   417  func (e BucketRemoteTargetNotFound) Error() string {
   418  	return "Remote target not found: " + e.Bucket
   419  }
   420  
   421  // RemoteTargetConnectionErr remote target connection failure.
   422  type RemoteTargetConnectionErr struct {
   423  	Err       error
   424  	Bucket    string
   425  	Endpoint  string
   426  	AccessKey string
   427  }
   428  
   429  func (e RemoteTargetConnectionErr) Error() string {
   430  	if e.Bucket != "" {
   431  		return fmt.Sprintf("Remote service endpoint offline, target bucket: %s or remote service credentials: %s invalid \n\t%s", e.Bucket, e.AccessKey, e.Err.Error())
   432  	}
   433  	return fmt.Sprintf("Remote service endpoint %s not available\n\t%s", e.Endpoint, e.Err.Error())
   434  }
   435  
   436  // BucketRemoteIdenticalToSource remote already exists for this target type.
   437  type BucketRemoteIdenticalToSource struct {
   438  	GenericError
   439  	Endpoint string
   440  }
   441  
   442  func (e BucketRemoteIdenticalToSource) Error() string {
   443  	return fmt.Sprintf("Remote service endpoint %s is self referential to current cluster", e.Endpoint)
   444  }
   445  
   446  // BucketRemoteAlreadyExists remote already exists for this target type.
   447  type BucketRemoteAlreadyExists GenericError
   448  
   449  func (e BucketRemoteAlreadyExists) Error() string {
   450  	return "Remote already exists for this bucket: " + e.Bucket
   451  }
   452  
   453  // BucketRemoteLabelInUse remote already exists for this target label.
   454  type BucketRemoteLabelInUse GenericError
   455  
   456  func (e BucketRemoteLabelInUse) Error() string {
   457  	return "Remote with this label already exists for this bucket: " + e.Bucket
   458  }
   459  
   460  // BucketRemoteArnTypeInvalid arn type for remote is not valid.
   461  type BucketRemoteArnTypeInvalid GenericError
   462  
   463  func (e BucketRemoteArnTypeInvalid) Error() string {
   464  	return "Remote ARN type not valid: " + e.Bucket
   465  }
   466  
   467  // BucketRemoteArnInvalid arn needs to be specified.
   468  type BucketRemoteArnInvalid GenericError
   469  
   470  func (e BucketRemoteArnInvalid) Error() string {
   471  	return "Remote ARN has invalid format: " + e.Bucket
   472  }
   473  
   474  // BucketRemoteRemoveDisallowed when replication configuration exists
   475  type BucketRemoteRemoveDisallowed GenericError
   476  
   477  func (e BucketRemoteRemoveDisallowed) Error() string {
   478  	return "Replication configuration exists with this ARN:" + e.Bucket
   479  }
   480  
   481  // BucketRemoteTargetNotVersioned remote target does not have versioning enabled.
   482  type BucketRemoteTargetNotVersioned GenericError
   483  
   484  func (e BucketRemoteTargetNotVersioned) Error() string {
   485  	return "Remote target does not have versioning enabled: " + e.Bucket
   486  }
   487  
   488  // BucketReplicationSourceNotVersioned replication source does not have versioning enabled.
   489  type BucketReplicationSourceNotVersioned GenericError
   490  
   491  func (e BucketReplicationSourceNotVersioned) Error() string {
   492  	return "Replication source does not have versioning enabled: " + e.Bucket
   493  }
   494  
   495  // TransitionStorageClassNotFound remote tier not configured.
   496  type TransitionStorageClassNotFound GenericError
   497  
   498  func (e TransitionStorageClassNotFound) Error() string {
   499  	return "Transition storage class not found "
   500  }
   501  
   502  // InvalidObjectState restore-object doesn't apply for the current state of the object.
   503  type InvalidObjectState GenericError
   504  
   505  func (e InvalidObjectState) Error() string {
   506  	return "The operation is not valid for the current state of the object " + e.Bucket + "/" + e.Object + "(" + e.VersionID + ")"
   507  }
   508  
   509  // Bucket related errors.
   510  
   511  // BucketNameInvalid - bucketname provided is invalid.
   512  type BucketNameInvalid GenericError
   513  
   514  // Error returns string an error formatted as the given text.
   515  func (e BucketNameInvalid) Error() string {
   516  	return "Bucket name invalid: " + e.Bucket
   517  }
   518  
   519  // Object related errors.
   520  
   521  // ObjectNameInvalid - object name provided is invalid.
   522  type ObjectNameInvalid GenericError
   523  
   524  // ObjectNameTooLong - object name too long.
   525  type ObjectNameTooLong GenericError
   526  
   527  // ObjectNamePrefixAsSlash - object name has a slash as prefix.
   528  type ObjectNamePrefixAsSlash GenericError
   529  
   530  // Error returns string an error formatted as the given text.
   531  func (e ObjectNameInvalid) Error() string {
   532  	return "Object name invalid: " + e.Bucket + "/" + e.Object
   533  }
   534  
   535  // Error returns string an error formatted as the given text.
   536  func (e ObjectNameTooLong) Error() string {
   537  	return "Object name too long: " + e.Bucket + "/" + e.Object
   538  }
   539  
   540  // Error returns string an error formatted as the given text.
   541  func (e ObjectNamePrefixAsSlash) Error() string {
   542  	return "Object name contains forward slash as prefix: " + e.Bucket + "/" + e.Object
   543  }
   544  
   545  // AllAccessDisabled All access to this object has been disabled
   546  type AllAccessDisabled GenericError
   547  
   548  // Error returns string an error formatted as the given text.
   549  func (e AllAccessDisabled) Error() string {
   550  	return "All access to this object has been disabled"
   551  }
   552  
   553  // IncompleteBody You did not provide the number of bytes specified by the Content-Length HTTP header.
   554  type IncompleteBody GenericError
   555  
   556  // Error returns string an error formatted as the given text.
   557  func (e IncompleteBody) Error() string {
   558  	return e.Bucket + "/" + e.Object + " has incomplete body"
   559  }
   560  
   561  // InvalidRange - invalid range typed error.
   562  type InvalidRange struct {
   563  	OffsetBegin  int64
   564  	OffsetEnd    int64
   565  	ResourceSize int64
   566  }
   567  
   568  func (e InvalidRange) Error() string {
   569  	return fmt.Sprintf("The requested range \"bytes %d -> %d of %d\" is not satisfiable.", e.OffsetBegin, e.OffsetEnd, e.ResourceSize)
   570  }
   571  
   572  // ObjectTooLarge error returned when the size of the object > max object size allowed (5G) per request.
   573  type ObjectTooLarge GenericError
   574  
   575  func (e ObjectTooLarge) Error() string {
   576  	return "size of the object greater than what is allowed(5G)"
   577  }
   578  
   579  // ObjectTooSmall error returned when the size of the object < what is expected.
   580  type ObjectTooSmall GenericError
   581  
   582  func (e ObjectTooSmall) Error() string {
   583  	return "size of the object less than what is expected"
   584  }
   585  
   586  // OperationTimedOut - a timeout occurred.
   587  type OperationTimedOut struct{}
   588  
   589  func (e OperationTimedOut) Error() string {
   590  	return "Operation timed out"
   591  }
   592  
   593  // Multipart related errors.
   594  
   595  // MalformedUploadID malformed upload id.
   596  type MalformedUploadID struct {
   597  	UploadID string
   598  }
   599  
   600  func (e MalformedUploadID) Error() string {
   601  	return "Malformed upload id " + e.UploadID
   602  }
   603  
   604  // InvalidUploadID invalid upload id.
   605  type InvalidUploadID struct {
   606  	Bucket   string
   607  	Object   string
   608  	UploadID string
   609  }
   610  
   611  func (e InvalidUploadID) Error() string {
   612  	return "Invalid upload id " + e.UploadID
   613  }
   614  
   615  // InvalidPart One or more of the specified parts could not be found
   616  type InvalidPart struct {
   617  	PartNumber int
   618  	ExpETag    string
   619  	GotETag    string
   620  }
   621  
   622  func (e InvalidPart) Error() string {
   623  	return fmt.Sprintf("Specified part could not be found. PartNumber %d, Expected %s, got %s",
   624  		e.PartNumber, e.ExpETag, e.GotETag)
   625  }
   626  
   627  // PartTooSmall - error if part size is less than 5MB.
   628  type PartTooSmall struct {
   629  	PartSize   int64
   630  	PartNumber int
   631  	PartETag   string
   632  }
   633  
   634  func (e PartTooSmall) Error() string {
   635  	return fmt.Sprintf("Part size for %d should be at least 5MB", e.PartNumber)
   636  }
   637  
   638  // PartTooBig returned if size of part is bigger than the allowed limit.
   639  type PartTooBig struct{}
   640  
   641  func (e PartTooBig) Error() string {
   642  	return "Part size bigger than the allowed limit"
   643  }
   644  
   645  // InvalidETag error returned when the etag has changed on disk
   646  type InvalidETag struct{}
   647  
   648  func (e InvalidETag) Error() string {
   649  	return "etag of the object has changed"
   650  }
   651  
   652  // BackendDown is returned for network errors
   653  type BackendDown struct {
   654  	Err string
   655  }
   656  
   657  func (e BackendDown) Error() string {
   658  	return e.Err
   659  }
   660  
   661  // NotImplemented If a feature is not implemented
   662  type NotImplemented struct {
   663  	Message string
   664  }
   665  
   666  func (e NotImplemented) Error() string {
   667  	return e.Message
   668  }
   669  
   670  // UnsupportedMetadata - unsupported metadata
   671  type UnsupportedMetadata struct{}
   672  
   673  func (e UnsupportedMetadata) Error() string {
   674  	return "Unsupported headers in Metadata"
   675  }
   676  
   677  // isErrBucketNotFound - Check if error type is BucketNotFound.
   678  func isErrBucketNotFound(err error) bool {
   679  	var bkNotFound BucketNotFound
   680  	return errors.As(err, &bkNotFound)
   681  }
   682  
   683  // isErrReadQuorum check if the error type is InsufficientReadQuorum
   684  func isErrReadQuorum(err error) bool {
   685  	var rquorum InsufficientReadQuorum
   686  	return errors.As(err, &rquorum)
   687  }
   688  
   689  // isErrWriteQuorum check if the error type is InsufficientWriteQuorum
   690  func isErrWriteQuorum(err error) bool {
   691  	var rquorum InsufficientWriteQuorum
   692  	return errors.As(err, &rquorum)
   693  }
   694  
   695  // isErrObjectNotFound - Check if error type is ObjectNotFound.
   696  func isErrObjectNotFound(err error) bool {
   697  	var objNotFound ObjectNotFound
   698  	return errors.As(err, &objNotFound)
   699  }
   700  
   701  // isErrVersionNotFound - Check if error type is VersionNotFound.
   702  func isErrVersionNotFound(err error) bool {
   703  	var versionNotFound VersionNotFound
   704  	return errors.As(err, &versionNotFound)
   705  }
   706  
   707  // isErrSignatureDoesNotMatch - Check if error type is SignatureDoesNotMatch.
   708  func isErrSignatureDoesNotMatch(err error) bool {
   709  	var signatureDoesNotMatch SignatureDoesNotMatch
   710  	return errors.As(err, &signatureDoesNotMatch)
   711  }
   712  
   713  // PreConditionFailed - Check if copy precondition failed
   714  type PreConditionFailed struct{}
   715  
   716  func (e PreConditionFailed) Error() string {
   717  	return "At least one of the pre-conditions you specified did not hold"
   718  }
   719  
   720  func isErrPreconditionFailed(err error) bool {
   721  	_, ok := err.(PreConditionFailed)
   722  	return ok
   723  }
   724  
   725  // isErrMethodNotAllowed - Check if error type is MethodNotAllowed.
   726  func isErrMethodNotAllowed(err error) bool {
   727  	var methodNotAllowed MethodNotAllowed
   728  	return errors.As(err, &methodNotAllowed)
   729  }
   730  
   731  func isErrInvalidRange(err error) bool {
   732  	_, ok := err.(InvalidRange)
   733  	return ok
   734  }
   735  
   736  // ReplicationPermissionCheck - Check if error type is ReplicationPermissionCheck.
   737  type ReplicationPermissionCheck struct{}
   738  
   739  func (e ReplicationPermissionCheck) Error() string {
   740  	return "Replication permission validation requests cannot be completed"
   741  }
   742  
   743  func isReplicationPermissionCheck(err error) bool {
   744  	_, ok := err.(ReplicationPermissionCheck)
   745  	return ok
   746  }