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 }