github.com/onflow/atree@v0.6.0/errors.go (about)

     1  /*
     2   * Atree - Scalable Arrays and Ordered Maps
     3   *
     4   * Copyright 2021 Dapper Labs, Inc.
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package atree
    20  
    21  import (
    22  	"errors"
    23  	"fmt"
    24  	"runtime/debug"
    25  )
    26  
    27  type ExternalError struct {
    28  	msg string
    29  	err error
    30  }
    31  
    32  func NewExternalError(err error, msg string) error {
    33  	return &ExternalError{msg: msg, err: err}
    34  }
    35  
    36  func (e *ExternalError) Error() string {
    37  	if e.msg == "" {
    38  		return e.err.Error()
    39  	}
    40  	return fmt.Sprintf("%s: %s", e.msg, e.err.Error())
    41  }
    42  
    43  func (e *ExternalError) Unwrap() error {
    44  	return e.err
    45  }
    46  
    47  type UserError struct {
    48  	err error
    49  }
    50  
    51  func NewUserError(err error) error {
    52  	return &UserError{err: err}
    53  }
    54  
    55  func (e *UserError) Error() string {
    56  	return e.err.Error()
    57  }
    58  
    59  func (e *UserError) Unwrap() error {
    60  	return e.err
    61  }
    62  
    63  type FatalError struct {
    64  	err error
    65  }
    66  
    67  func NewFatalError(err error) error {
    68  	return &FatalError{err: err}
    69  }
    70  
    71  func (e *FatalError) Error() string {
    72  	return e.err.Error()
    73  }
    74  
    75  func (e *FatalError) Unwrap() error {
    76  	return e.err
    77  }
    78  
    79  // SliceOutOfBoundsError is returned when index for array slice is out of bounds.
    80  type SliceOutOfBoundsError struct {
    81  	startIndex uint64
    82  	endIndex   uint64
    83  	min        uint64
    84  	max        uint64
    85  }
    86  
    87  // NewSliceOutOfBoundsError constructs a SliceOutOfBoundsError.
    88  func NewSliceOutOfBoundsError(startIndex, endIndex, min, max uint64) error {
    89  	return NewUserError(
    90  		&SliceOutOfBoundsError{
    91  			startIndex: startIndex,
    92  			endIndex:   endIndex,
    93  			min:        min,
    94  			max:        max,
    95  		},
    96  	)
    97  }
    98  
    99  func (e *SliceOutOfBoundsError) Error() string {
   100  	return fmt.Sprintf("slice [%d:%d] is out of bounds with range %d-%d", e.startIndex, e.endIndex, e.min, e.max)
   101  }
   102  
   103  // InvalidSliceIndexError is returned when array slice index is invalid, such as startIndex > endIndex
   104  // This error can be returned even when startIndex and endIndex are both within bounds.
   105  type InvalidSliceIndexError struct {
   106  	startIndex uint64
   107  	endIndex   uint64
   108  }
   109  
   110  // NewInvalidSliceIndexError constructs an InvalidSliceIndexError
   111  func NewInvalidSliceIndexError(startIndex, endIndex uint64) error {
   112  	return NewUserError(
   113  		&InvalidSliceIndexError{
   114  			startIndex: startIndex,
   115  			endIndex:   endIndex,
   116  		},
   117  	)
   118  }
   119  
   120  func (e *InvalidSliceIndexError) Error() string {
   121  	return fmt.Sprintf("invalid slice index: %d > %d", e.startIndex, e.endIndex)
   122  }
   123  
   124  // IndexOutOfBoundsError is returned when get, insert or delete operation is attempted on an array index which is out of bounds
   125  type IndexOutOfBoundsError struct {
   126  	index uint64
   127  	min   uint64
   128  	max   uint64
   129  }
   130  
   131  // NewIndexOutOfBoundsError constructs a IndexOutOfBoundsError
   132  func NewIndexOutOfBoundsError(index, min, max uint64) error {
   133  	return NewUserError(
   134  		&IndexOutOfBoundsError{
   135  			index: index,
   136  			min:   min,
   137  			max:   max,
   138  		},
   139  	)
   140  }
   141  
   142  func (e *IndexOutOfBoundsError) Error() string {
   143  	return fmt.Sprintf("index %d is outside required range (%d-%d)", e.index, e.min, e.max)
   144  }
   145  
   146  // NotValueError is returned when we try to create Value objects from non-root slabs.
   147  type NotValueError struct {
   148  	id StorageID
   149  }
   150  
   151  // NewNotValueError constructs a NotValueError.
   152  func NewNotValueError(id StorageID) error {
   153  	return NewFatalError(&NotValueError{id: id})
   154  }
   155  
   156  func (e *NotValueError) Error() string {
   157  	return fmt.Sprintf("slab (%s) cannot be used to create Value object", e.id)
   158  }
   159  
   160  // DuplicateKeyError is returned when the duplicate key is found in the dictionary when none is expected.
   161  type DuplicateKeyError struct {
   162  	key interface{}
   163  }
   164  
   165  func NewDuplicateKeyError(key interface{}) error {
   166  	return NewFatalError(&DuplicateKeyError{key: key})
   167  }
   168  
   169  func (e *DuplicateKeyError) Error() string {
   170  	return fmt.Sprintf("duplicate key (%s)", e.key)
   171  }
   172  
   173  // KeyNotFoundError is returned when the key not found in the dictionary
   174  type KeyNotFoundError struct {
   175  	key interface{}
   176  }
   177  
   178  // NewKeyNotFoundError constructs a KeyNotFoundError
   179  func NewKeyNotFoundError(key interface{}) error {
   180  	return NewUserError(&KeyNotFoundError{key: key})
   181  }
   182  
   183  func (e *KeyNotFoundError) Error() string {
   184  	return fmt.Sprintf("key (%s) not found", e.key)
   185  }
   186  
   187  // HashSeedUninitializedError is a fatal error returned when hash seed is uninitialized.
   188  type HashSeedUninitializedError struct {
   189  }
   190  
   191  func NewHashSeedUninitializedError() error {
   192  	return NewFatalError(&HashSeedUninitializedError{})
   193  }
   194  
   195  func (e *HashSeedUninitializedError) Error() string {
   196  	return "uninitialized hash seed"
   197  }
   198  
   199  // HashError is a fatal error returned when hash calculation fails
   200  type HashError struct {
   201  	err error
   202  }
   203  
   204  // NewHashError constructs a HashError
   205  func NewHashError(err error) error {
   206  	return NewFatalError(&HashError{err: err})
   207  }
   208  
   209  func (e *HashError) Error() string {
   210  	return fmt.Sprintf("hasher error: %s", e.err.Error())
   211  }
   212  
   213  // StorageIDError is returned when storage id can't be created or it's invalid.
   214  type StorageIDError struct {
   215  	msg string
   216  }
   217  
   218  // NewStorageIDError constructs a fatal error of StorageIDError.
   219  func NewStorageIDError(msg string) error {
   220  	return NewFatalError(&StorageIDError{msg: msg})
   221  }
   222  
   223  // NewStorageIDErrorf constructs a fatal error of StorageIDError.
   224  func NewStorageIDErrorf(msg string, args ...interface{}) error {
   225  	return NewStorageIDError(fmt.Sprintf(msg, args...))
   226  }
   227  
   228  func (e *StorageIDError) Error() string {
   229  	return fmt.Sprintf("storage id error: %s", e.msg)
   230  }
   231  
   232  // SlabNotFoundError is always a fatal error returned when an slab is not found
   233  type SlabNotFoundError struct {
   234  	storageID StorageID
   235  	err       error
   236  }
   237  
   238  // NewSlabNotFoundError constructs a SlabNotFoundError
   239  func NewSlabNotFoundError(storageID StorageID, err error) error {
   240  	return NewFatalError(&SlabNotFoundError{storageID: storageID, err: err})
   241  }
   242  
   243  // NewSlabNotFoundErrorf constructs a new SlabNotFoundError with error formating
   244  func NewSlabNotFoundErrorf(storageID StorageID, msg string, args ...interface{}) error {
   245  	return NewSlabNotFoundError(storageID, fmt.Errorf(msg, args...))
   246  }
   247  
   248  func (e *SlabNotFoundError) Error() string {
   249  	return fmt.Sprintf("slab (%s) not found: %s", e.storageID.String(), e.err.Error())
   250  }
   251  
   252  // SlabSplitError is always a fatal error returned when splitting an slab has failed
   253  type SlabSplitError struct {
   254  	err error
   255  }
   256  
   257  // NewSlabSplitError constructs a SlabSplitError
   258  func NewSlabSplitError(err error) error {
   259  	return NewFatalError(&SlabSplitError{err: err})
   260  }
   261  
   262  // NewSlabSplitErrorf constructs a new SlabSplitError with error formating
   263  func NewSlabSplitErrorf(msg string, args ...interface{}) error {
   264  	return NewSlabSplitError(fmt.Errorf(msg, args...))
   265  }
   266  
   267  func (e *SlabSplitError) Error() string {
   268  	return fmt.Sprintf("slab failed to split: %s", e.err.Error())
   269  }
   270  
   271  // SlabMergeError is always a fatal error returned when merging two slabs fails
   272  type SlabMergeError struct {
   273  	err error
   274  }
   275  
   276  // NewSlabMergeError constructs a SlabMergeError
   277  func NewSlabMergeError(err error) error {
   278  	return NewFatalError(&SlabMergeError{err: err})
   279  }
   280  
   281  // NewSlabMergeErrorf constructs a new SlabMergeError with error formating
   282  func NewSlabMergeErrorf(msg string, args ...interface{}) error {
   283  	return NewSlabMergeError(fmt.Errorf(msg, args...))
   284  }
   285  
   286  func (e *SlabMergeError) Error() string {
   287  	return fmt.Sprintf("slabs failed to merge: %s", e.err.Error())
   288  }
   289  
   290  // SlabRebalanceError is always a fatal error returned when rebalancing a slab has failed
   291  type SlabRebalanceError struct {
   292  	err error
   293  }
   294  
   295  // NewSlabRebalanceError constructs a SlabRebalanceError
   296  func NewSlabRebalanceError(err error) error {
   297  	return NewFatalError(&SlabRebalanceError{err: err})
   298  }
   299  
   300  // NewSlabErrorf constructs a new SlabError with error formating
   301  func NewSlabRebalanceErrorf(msg string, args ...interface{}) error {
   302  	return NewSlabRebalanceError(fmt.Errorf(msg, args...))
   303  }
   304  
   305  func (e *SlabRebalanceError) Error() string {
   306  	return fmt.Sprintf("slabs failed to rebalance: %s", e.err.Error())
   307  }
   308  
   309  // SlabError is a always fatal error returned when something is wrong with the content or type of the slab
   310  // you can make this a fatal error by calling Fatal()
   311  type SlabDataError struct {
   312  	err error
   313  }
   314  
   315  // NewSlabDataError constructs a SlabDataError
   316  func NewSlabDataError(err error) error {
   317  	return NewFatalError(&SlabDataError{err: err})
   318  }
   319  
   320  // NewSlabDataErrorf constructs a new SlabError with error formating
   321  func NewSlabDataErrorf(msg string, args ...interface{}) error {
   322  	return NewSlabDataError(fmt.Errorf(msg, args...))
   323  }
   324  
   325  func (e *SlabDataError) Error() string {
   326  	return fmt.Sprintf("slab data error: %s", e.err.Error())
   327  }
   328  
   329  // EncodingError is a fatal error returned when a encoding operation fails
   330  type EncodingError struct {
   331  	err error
   332  }
   333  
   334  // NewEncodingError constructs a EncodingError
   335  func NewEncodingError(err error) error {
   336  	return NewFatalError(&EncodingError{err: err})
   337  }
   338  
   339  // NewEncodingErrorf constructs a new EncodingError with error formating
   340  func NewEncodingErrorf(msg string, args ...interface{}) error {
   341  	return NewEncodingError(fmt.Errorf(msg, args...))
   342  }
   343  
   344  func (e *EncodingError) Error() string {
   345  	return fmt.Sprintf("encoding error: %s", e.err.Error())
   346  }
   347  
   348  // DecodingError is a fatal error returned when a decoding operation fails
   349  type DecodingError struct {
   350  	err error
   351  }
   352  
   353  // NewDecodingError constructs a DecodingError
   354  func NewDecodingError(err error) error {
   355  	return NewFatalError(&DecodingError{err: err})
   356  }
   357  
   358  // NewDecodingErrorf constructs a new DecodingError with error formating
   359  func NewDecodingErrorf(msg string, args ...interface{}) error {
   360  	return NewDecodingError(fmt.Errorf(msg, args...))
   361  }
   362  
   363  func (e *DecodingError) Error() string {
   364  	return fmt.Sprintf("decoding error: %s", e.err.Error())
   365  }
   366  
   367  // NotImplementedError is a fatal error returned when a method is called which is not yet implemented
   368  // this is a temporary error
   369  type NotImplementedError struct {
   370  	methodName string
   371  }
   372  
   373  // NewNotImplementedError constructs a NotImplementedError
   374  func NewNotImplementedError(methodName string) error {
   375  	return NewFatalError(&NotImplementedError{methodName: methodName})
   376  }
   377  
   378  func (e *NotImplementedError) Error() string {
   379  	return fmt.Sprintf("method (%s) is not implemented.", e.methodName)
   380  }
   381  
   382  // HashLevelError is a fatal error returned when hash level is wrong.
   383  type HashLevelError struct {
   384  	msg string
   385  }
   386  
   387  // NewHashLevelError constructs a HashLevelError
   388  func NewHashLevelErrorf(msg string, args ...interface{}) error {
   389  	return NewFatalError(&HashLevelError{msg: fmt.Sprintf(msg, args...)})
   390  }
   391  
   392  func (e *HashLevelError) Error() string {
   393  	return fmt.Sprintf("atree hash level error: %s", e.msg)
   394  }
   395  
   396  // NotApplicableError is a fatal error returned when a not applicable method is called
   397  type NotApplicableError struct {
   398  	typeName, interfaceName, methodName string
   399  }
   400  
   401  // NewNotApplicableError constructs a NotImplementedError
   402  func NewNotApplicableError(typeName, interfaceName, methodName string) error {
   403  	return NewFatalError(
   404  		&NotApplicableError{
   405  			typeName:      typeName,
   406  			interfaceName: interfaceName,
   407  			methodName:    methodName,
   408  		})
   409  }
   410  
   411  func (e *NotApplicableError) Error() string {
   412  	return fmt.Sprintf("%s.%s is not applicable for type %s", e.interfaceName, e.methodName, e.typeName)
   413  }
   414  
   415  // UnreachableError is used by panic when unreachable code is reached.
   416  // This is copied from Cadence.
   417  type UnreachableError struct {
   418  	Stack []byte
   419  }
   420  
   421  func NewUnreachableError() error {
   422  	return NewFatalError(&UnreachableError{Stack: debug.Stack()})
   423  }
   424  
   425  func (e UnreachableError) Error() string {
   426  	return fmt.Sprintf("unreachable\n%s", e.Stack)
   427  }
   428  
   429  // CollisionLimitError is a fatal error returned when a noncryptographic hash collision
   430  // would exceed collision limit (per digest per map) we enforce in the first level.
   431  type CollisionLimitError struct {
   432  	collisionLimitPerDigest uint32 // limit <= 255 is recommended, larger values are useful for tests
   433  }
   434  
   435  // NewCollisionLimitError constructs a CollisionLimitError
   436  func NewCollisionLimitError(collisionLimitPerDigest uint32) error {
   437  	return NewFatalError(&CollisionLimitError{collisionLimitPerDigest: collisionLimitPerDigest})
   438  }
   439  
   440  func (e *CollisionLimitError) Error() string {
   441  	return fmt.Sprintf("collision limit per digest %d already reached", e.collisionLimitPerDigest)
   442  }
   443  
   444  // MapElementCountError is a fatal error returned when element count is unexpected.
   445  // It is an implemtation error.
   446  type MapElementCountError struct {
   447  	msg string
   448  }
   449  
   450  // NewMapElementCountError constructs a MapElementCountError.
   451  func NewMapElementCountError(msg string) error {
   452  	return NewFatalError(&MapElementCountError{msg: msg})
   453  }
   454  
   455  func (e *MapElementCountError) Error() string {
   456  	return e.msg
   457  }
   458  
   459  func wrapErrorAsExternalErrorIfNeeded(err error) error {
   460  	return wrapErrorfAsExternalErrorIfNeeded(err, "")
   461  }
   462  
   463  func wrapErrorfAsExternalErrorIfNeeded(err error, msg string) error {
   464  	if err == nil {
   465  		return nil
   466  	}
   467  
   468  	var userError *UserError
   469  	var fatalError *FatalError
   470  	var externalError *ExternalError
   471  
   472  	if errors.As(err, &userError) ||
   473  		errors.As(err, &fatalError) ||
   474  		errors.As(err, &externalError) {
   475  		// No-op if err is already categorized.
   476  		return err
   477  	}
   478  
   479  	// Create new external error wrapping err with context.
   480  	return NewExternalError(err, msg)
   481  }