github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/errors.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package libkbfs 6 7 import ( 8 "fmt" 9 "time" 10 11 "github.com/keybase/client/go/kbfs/data" 12 "github.com/keybase/client/go/kbfs/idutil" 13 "github.com/keybase/client/go/kbfs/kbfsblock" 14 "github.com/keybase/client/go/kbfs/kbfscrypto" 15 "github.com/keybase/client/go/kbfs/kbfsmd" 16 "github.com/keybase/client/go/kbfs/tlf" 17 "github.com/keybase/client/go/kbfs/tlfhandle" 18 kbname "github.com/keybase/client/go/kbun" 19 "github.com/keybase/client/go/protocol/keybase1" 20 ) 21 22 // WrapError simply wraps an error in a fmt.Stringer interface, so 23 // that it can be reported. 24 type WrapError struct { 25 Err error 26 } 27 28 // String implements the fmt.Stringer interface for WrapError 29 func (e WrapError) String() string { 30 return e.Err.Error() 31 } 32 33 // InvalidBlockRefError indicates an invalid block reference was 34 // encountered. 35 type InvalidBlockRefError struct { 36 ref data.BlockRef 37 } 38 39 func (e InvalidBlockRefError) Error() string { 40 return fmt.Sprintf("Invalid block ref %s", e.ref) 41 } 42 43 // InvalidPathError indicates an invalid path was encountered. 44 type InvalidPathError struct { 45 p data.Path 46 } 47 48 // Error implements the error interface for InvalidPathError. 49 func (e InvalidPathError) Error() string { 50 return fmt.Sprintf("Invalid path %s", e.p.DebugString()) 51 } 52 53 // InvalidParentPathError indicates a path without a valid parent was 54 // encountered. 55 type InvalidParentPathError struct { 56 p data.Path 57 } 58 59 // Error implements the error interface for InvalidParentPathError. 60 func (e InvalidParentPathError) Error() string { 61 return fmt.Sprintf("Path with invalid parent %s", e.p.DebugString()) 62 } 63 64 // DirNotEmptyError indicates that the user tried to unlink a 65 // subdirectory that was not empty. 66 type DirNotEmptyError struct { 67 Name data.PathPartString 68 } 69 70 // Error implements the error interface for DirNotEmptyError 71 func (e DirNotEmptyError) Error() string { 72 return fmt.Sprintf("Directory %s is not empty and can't be removed", e.Name) 73 } 74 75 // TlfAccessError that the user tried to perform an unpermitted 76 // operation on a top-level folder. 77 type TlfAccessError struct { 78 ID tlf.ID 79 } 80 81 // Error implements the error interface for TlfAccessError 82 func (e TlfAccessError) Error() string { 83 return fmt.Sprintf("Operation not permitted on folder %s", e.ID) 84 } 85 86 // RenameAcrossDirsError indicates that the user tried to do an atomic 87 // rename across directories. 88 type RenameAcrossDirsError struct { 89 // ApplicationExecPath, if not empty, is the exec path of the application 90 // that issued the rename. 91 ApplicationExecPath string 92 } 93 94 // Error implements the error interface for RenameAcrossDirsError 95 func (e RenameAcrossDirsError) Error() string { 96 return "Cannot rename across directories" 97 } 98 99 // WriteUnsupportedError indicates an error when trying to write a file 100 type WriteUnsupportedError struct { 101 Filename string 102 } 103 104 // Error implements the error interface for WriteUnsupportedError 105 func (e WriteUnsupportedError) Error() string { 106 return fmt.Sprintf("Writing to %s is unsupported", e.Filename) 107 } 108 109 // WriteToReadonlyNodeError indicates an error when trying to write a 110 // node that's marked as read-only. 111 type WriteToReadonlyNodeError struct { 112 Filename string 113 } 114 115 // Error implements the error interface for WriteToReadonlyNodeError 116 func (e WriteToReadonlyNodeError) Error() string { 117 return fmt.Sprintf("%s is read-only and writes are not allowed", e.Filename) 118 } 119 120 // UnsupportedOpInUnlinkedDirError indicates an error when trying to 121 // create a file. 122 type UnsupportedOpInUnlinkedDirError struct { 123 Dirpath string 124 } 125 126 // Error implements the error interface for UnsupportedOpInUnlinkedDirError. 127 func (e UnsupportedOpInUnlinkedDirError) Error() string { 128 return fmt.Sprintf( 129 "Operation is unsupported in unlinked directory %s", e.Dirpath) 130 } 131 132 // NewWriteUnsupportedError returns unsupported error trying to write a file 133 func NewWriteUnsupportedError(filename string) error { 134 return WriteUnsupportedError{ 135 Filename: filename, 136 } 137 } 138 139 // NeedSelfRekeyError indicates that the folder in question needs to 140 // be rekeyed for the local device, and can be done so by one of the 141 // other user's devices. 142 type NeedSelfRekeyError struct { 143 Tlf tlf.CanonicalName 144 Err error 145 } 146 147 // Error implements the error interface for NeedSelfRekeyError 148 func (e NeedSelfRekeyError) Error() string { 149 return fmt.Sprintf("This device does not yet have read access to "+ 150 "directory %s, log into Keybase from one of your other "+ 151 "devices to grant access: %+v", 152 tlfhandle.BuildCanonicalPathForTlfName(tlf.Private, e.Tlf), e.Err) 153 } 154 155 // ToStatus exports error to status 156 func (e NeedSelfRekeyError) ToStatus() keybase1.Status { 157 kv := keybase1.StringKVPair{ 158 Key: "Tlf", 159 Value: string(e.Tlf), 160 } 161 return keybase1.Status{ 162 Code: int(keybase1.StatusCode_SCNeedSelfRekey), 163 Name: "SC_NEED_SELF_REKEY", 164 Desc: e.Error(), 165 Fields: []keybase1.StringKVPair{kv}, 166 } 167 } 168 169 // NeedOtherRekeyError indicates that the folder in question needs to 170 // be rekeyed for the local device, and can only done so by one of the 171 // other users. 172 type NeedOtherRekeyError struct { 173 Tlf tlf.CanonicalName 174 Err error 175 } 176 177 // Error implements the error interface for NeedOtherRekeyError 178 func (e NeedOtherRekeyError) Error() string { 179 return fmt.Sprintf("This device does not yet have read access to "+ 180 "directory %s, ask one of the other directory participants to "+ 181 "log into Keybase to grant you access automatically: %+v", 182 tlfhandle.BuildCanonicalPathForTlfName(tlf.Private, e.Tlf), e.Err) 183 } 184 185 // ToStatus exports error to status 186 func (e NeedOtherRekeyError) ToStatus() keybase1.Status { 187 kv := keybase1.StringKVPair{ 188 Key: "Tlf", 189 Value: string(e.Tlf), 190 } 191 return keybase1.Status{ 192 Code: int(keybase1.StatusCode_SCNeedOtherRekey), 193 Name: "SC_NEED_OTHER_REKEY", 194 Desc: e.Error(), 195 Fields: []keybase1.StringKVPair{kv}, 196 } 197 } 198 199 // NotFileBlockError indicates that a file block was expected but a 200 // block of a different type was found. 201 // 202 // ptr and branch should be filled in, but p may be empty. 203 type NotFileBlockError struct { 204 ptr data.BlockPointer 205 branch data.BranchName 206 p data.Path 207 } 208 209 func (e NotFileBlockError) Error() string { 210 return fmt.Sprintf("The block at %s is not a file block (branch=%s, path=%s)", e.ptr, e.branch, e.p) 211 } 212 213 // NotDirBlockError indicates that a file block was expected but a 214 // block of a different type was found. 215 // 216 // ptr and branch should be filled in, but p may be empty. 217 type NotDirBlockError struct { 218 ptr data.BlockPointer 219 branch data.BranchName 220 p data.Path 221 } 222 223 func (e NotDirBlockError) Error() string { 224 return fmt.Sprintf("The block at %s is not a dir block (branch=%s, path=%s)", e.ptr, e.branch, e.p) 225 } 226 227 // NotFileError indicates that the user tried to perform a 228 // file-specific operation on something that isn't a file. 229 type NotFileError struct { 230 path data.Path 231 } 232 233 // Error implements the error interface for NotFileError 234 func (e NotFileError) Error() string { 235 return fmt.Sprintf("%s is not a file (folder %s)", e.path, e.path.Tlf) 236 } 237 238 // NotDirError indicates that the user tried to perform a 239 // dir-specific operation on something that isn't a directory. 240 type NotDirError struct { 241 path data.Path 242 } 243 244 // Error implements the error interface for NotDirError 245 func (e NotDirError) Error() string { 246 return fmt.Sprintf("%s is not a directory (folder %s)", e.path, e.path.Tlf) 247 } 248 249 // BlockDecodeError indicates that a block couldn't be decoded as 250 // expected; probably it is the wrong type. 251 type BlockDecodeError struct { 252 decodeErr error 253 } 254 255 // Error implements the error interface for BlockDecodeError 256 func (e BlockDecodeError) Error() string { 257 return fmt.Sprintf("Decode error for a block: %v", e.decodeErr) 258 } 259 260 // BadCryptoError indicates that KBFS performed a bad crypto operation. 261 type BadCryptoError struct { 262 ID kbfsblock.ID 263 } 264 265 // Error implements the error interface for BadCryptoError 266 func (e BadCryptoError) Error() string { 267 return fmt.Sprintf("Bad crypto for block %v", e.ID) 268 } 269 270 // BadCryptoMDError indicates that KBFS performed a bad crypto 271 // operation, specifically on a MD object. 272 type BadCryptoMDError struct { 273 ID tlf.ID 274 } 275 276 // Error implements the error interface for BadCryptoMDError 277 func (e BadCryptoMDError) Error() string { 278 return fmt.Sprintf("Bad crypto for the metadata of directory %v", e.ID) 279 } 280 281 // BadMDError indicates that the system is storing corrupt MD object 282 // for the given TLF ID. 283 type BadMDError struct { 284 ID tlf.ID 285 } 286 287 // Error implements the error interface for BadMDError 288 func (e BadMDError) Error() string { 289 return fmt.Sprintf("Wrong format for metadata for directory %v", e.ID) 290 } 291 292 // MDMismatchError indicates an inconsistent or unverifiable MD object 293 // for the given top-level folder. 294 type MDMismatchError struct { 295 Revision kbfsmd.Revision 296 Dir string 297 TlfID tlf.ID 298 Err error 299 } 300 301 // Error implements the error interface for MDMismatchError 302 func (e MDMismatchError) Error() string { 303 return fmt.Sprintf("Could not verify metadata (revision=%d) for directory %s (id=%s): %s", 304 e.Revision, e.Dir, e.TlfID, e.Err) 305 } 306 307 // NoSuchMDError indicates that there is no MD object for the given 308 // folder, revision, and merged status. 309 type NoSuchMDError struct { 310 Tlf tlf.ID 311 Rev kbfsmd.Revision 312 BID kbfsmd.BranchID 313 } 314 315 // Error implements the error interface for NoSuchMDError 316 func (e NoSuchMDError) Error() string { 317 return fmt.Sprintf("Couldn't get metadata for folder %v, revision %d, "+ 318 "%s", e.Tlf, e.Rev, e.BID) 319 } 320 321 // InvalidDataVersionError indicates that an invalid data version was 322 // used. 323 type InvalidDataVersionError struct { 324 DataVer data.Ver 325 } 326 327 // Error implements the error interface for InvalidDataVersionError. 328 func (e InvalidDataVersionError) Error() string { 329 return fmt.Sprintf("Invalid data version %d", int(e.DataVer)) 330 } 331 332 // NewDataVersionError indicates that the data at the given path has 333 // been written using a new data version that our client doesn't 334 // understand. 335 type NewDataVersionError struct { 336 path data.Path 337 DataVer data.Ver 338 } 339 340 // Error implements the error interface for NewDataVersionError. 341 func (e NewDataVersionError) Error() string { 342 return fmt.Sprintf( 343 "The data at path %s is of a version (%d) that we can't read "+ 344 "(in folder %s)", 345 e.path, e.DataVer, e.path.Tlf) 346 } 347 348 // OutdatedVersionError indicates that we have encountered some new 349 // data version we don't understand, and the user should be prompted 350 // to upgrade. 351 type OutdatedVersionError struct { 352 } 353 354 // Error implements the error interface for OutdatedVersionError. 355 func (e OutdatedVersionError) Error() string { 356 return "Your software is out of date, and cannot read this data. " + 357 "Please use `keybase update check` to upgrade your software." 358 } 359 360 // InvalidVersionError indicates that we have encountered some new data version 361 // we don't understand, and we don't know how to handle it. 362 type InvalidVersionError struct { 363 msg string 364 } 365 366 // Error implements the error interface for InvalidVersionError. 367 func (e InvalidVersionError) Error() string { 368 if e.msg != "" { 369 return e.msg 370 } 371 return "The version provided is not valid." 372 } 373 374 // TooLowByteCountError indicates that size of a block is smaller than 375 // the expected size. 376 type TooLowByteCountError struct { 377 ExpectedMinByteCount int 378 ByteCount int 379 } 380 381 // Error implements the error interface for TooLowByteCountError 382 func (e TooLowByteCountError) Error() string { 383 return fmt.Sprintf("Expected at least %d bytes, got %d bytes", 384 e.ExpectedMinByteCount, e.ByteCount) 385 } 386 387 // InconsistentEncodedSizeError is raised when a dirty block has a 388 // non-zero encoded size. 389 type InconsistentEncodedSizeError struct { 390 info data.BlockInfo 391 } 392 393 // Error implements the error interface for InconsistentEncodedSizeError 394 func (e InconsistentEncodedSizeError) Error() string { 395 return fmt.Sprintf("Block pointer to dirty block %v with non-zero "+ 396 "encoded size = %d bytes", e.info.ID, e.info.EncodedSize) 397 } 398 399 // MDWriteNeededInRequest indicates that the system needs MD write 400 // permissions to successfully complete an operation, so it should 401 // retry in mdWrite mode. 402 type MDWriteNeededInRequest struct { 403 } 404 405 // Error implements the error interface for MDWriteNeededInRequest 406 func (e MDWriteNeededInRequest) Error() string { 407 return "This request needs MD write access, but doesn't have it." 408 } 409 410 // VerifyingKeyNotFoundError indicates that a verifying key matching 411 // the given one couldn't be found. 412 type VerifyingKeyNotFoundError struct { 413 key kbfscrypto.VerifyingKey 414 } 415 416 func (e VerifyingKeyNotFoundError) Error() string { 417 return fmt.Sprintf("Could not find verifying key %s", e.key) 418 } 419 420 // UnverifiableTlfUpdateError indicates that a MD update could not be 421 // verified. 422 type UnverifiableTlfUpdateError struct { 423 Tlf string 424 User kbname.NormalizedUsername 425 Err error 426 } 427 428 // Error implements the error interface for UnverifiableTlfUpdateError. 429 func (e UnverifiableTlfUpdateError) Error() string { 430 return fmt.Sprintf("%s was last written by an unknown device claiming "+ 431 "to belong to user %s. The device has possibly been revoked by the "+ 432 "user. Use `keybase log send` to file an issue with the Keybase "+ 433 "admins.", e.Tlf, e.User) 434 } 435 436 // KeyCacheMissError indicates that a key matching the given TLF ID 437 // and key generation wasn't found in cache. 438 type KeyCacheMissError struct { 439 tlf tlf.ID 440 keyGen kbfsmd.KeyGen 441 } 442 443 // Error implements the error interface for KeyCacheMissError. 444 func (e KeyCacheMissError) Error() string { 445 return fmt.Sprintf("Could not find key with tlf=%s, keyGen=%d", e.tlf, e.keyGen) 446 } 447 448 // KeyCacheHitError indicates that a key matching the given TLF ID 449 // and key generation was found in cache but the object type was unknown. 450 type KeyCacheHitError struct { 451 tlf tlf.ID 452 keyGen kbfsmd.KeyGen 453 } 454 455 // Error implements the error interface for KeyCacheHitError. 456 func (e KeyCacheHitError) Error() string { 457 return fmt.Sprintf("Invalid key with tlf=%s, keyGen=%d", e.tlf, e.keyGen) 458 } 459 460 // NoKeysError indicates that no keys were provided for a decryption allowing 461 // multiple device keys 462 type NoKeysError struct{} 463 464 func (e NoKeysError) Error() string { 465 return "No keys provided" 466 } 467 468 // WrongOpsError indicates that an unexpected path got passed into a 469 // FolderBranchOps instance 470 type WrongOpsError struct { 471 nodeFB data.FolderBranch 472 opsFB data.FolderBranch 473 } 474 475 // Error implements the error interface for WrongOpsError. 476 func (e WrongOpsError) Error() string { 477 return fmt.Sprintf("Ops for folder %v, branch %s, was given path %s, "+ 478 "branch %s", e.opsFB.Tlf, e.opsFB.Branch, e.nodeFB.Tlf, e.nodeFB.Branch) 479 } 480 481 // NodeNotFoundError indicates that we tried to find a node for the 482 // given BlockPointer and failed. 483 type NodeNotFoundError struct { 484 ptr data.BlockPointer 485 } 486 487 // Error implements the error interface for NodeNotFoundError. 488 func (e NodeNotFoundError) Error() string { 489 return fmt.Sprintf("No node found for pointer %v", e.ptr) 490 } 491 492 // ParentNodeNotFoundError indicates that we tried to update a Node's 493 // parent with a BlockPointer that we don't yet know about. 494 type ParentNodeNotFoundError struct { 495 parent data.BlockRef 496 } 497 498 // Error implements the error interface for ParentNodeNotFoundError. 499 func (e ParentNodeNotFoundError) Error() string { 500 return fmt.Sprintf("No such parent node found for %v", e.parent) 501 } 502 503 // EmptyNameError indicates that the user tried to use an empty name 504 // for the given BlockRef. 505 type EmptyNameError struct { 506 ref data.BlockRef 507 } 508 509 // Error implements the error interface for EmptyNameError. 510 func (e EmptyNameError) Error() string { 511 return fmt.Sprintf("Cannot use empty name for %v", e.ref) 512 } 513 514 // KeyHalfMismatchError is returned when the key server doesn't return the expected key half. 515 type KeyHalfMismatchError struct { 516 Expected kbfscrypto.TLFCryptKeyServerHalfID 517 Actual kbfscrypto.TLFCryptKeyServerHalfID 518 } 519 520 // Error implements the error interface for KeyHalfMismatchError. 521 func (e KeyHalfMismatchError) Error() string { 522 return fmt.Sprintf("Key mismatch, expected ID: %s, actual ID: %s", 523 e.Expected, e.Actual) 524 } 525 526 // MDServerDisconnected indicates the MDServer has been disconnected for clients waiting 527 // on an update channel. 528 type MDServerDisconnected struct { 529 } 530 531 // Error implements the error interface for MDServerDisconnected. 532 func (e MDServerDisconnected) Error() string { 533 return "MDServer is disconnected" 534 } 535 536 // MDUpdateInvertError indicates that we tried to apply a revision that 537 // was not the next in line. 538 type MDUpdateInvertError struct { 539 rev kbfsmd.Revision 540 curr kbfsmd.Revision 541 } 542 543 // Error implements the error interface for MDUpdateInvertError. 544 func (e MDUpdateInvertError) Error() string { 545 return fmt.Sprintf("MD revision %d isn't next in line for our "+ 546 "current revision %d while inverting", e.rev, e.curr) 547 } 548 549 // NotPermittedWhileDirtyError indicates that some operation failed 550 // because of outstanding dirty files, and may be retried later. 551 type NotPermittedWhileDirtyError struct { 552 } 553 554 // Error implements the error interface for NotPermittedWhileDirtyError. 555 func (e NotPermittedWhileDirtyError) Error() string { 556 return "Not permitted while writes are dirty" 557 } 558 559 // NoChainFoundError indicates that a conflict resolution chain 560 // corresponding to the given pointer could not be found. 561 type NoChainFoundError struct { 562 ptr data.BlockPointer 563 } 564 565 // Error implements the error interface for NoChainFoundError. 566 func (e NoChainFoundError) Error() string { 567 return fmt.Sprintf("No chain found for %v", e.ptr) 568 } 569 570 // DisallowedPrefixError indicates that the user attempted to create 571 // an entry using a name with a disallowed prefix. 572 type DisallowedPrefixError struct { 573 name data.PathPartString 574 prefix string 575 } 576 577 // Error implements the error interface for DisallowedPrefixError. 578 func (e DisallowedPrefixError) Error() string { 579 return fmt.Sprintf("Cannot create %s because it has the prefix %s", 580 e.name, e.prefix) 581 } 582 583 // DisallowedNameError indicates that the user attempted to create an 584 // entry using a disallowed name. It includes the plaintext name on 585 // purpose, for clarity in the error message. 586 type DisallowedNameError struct { 587 name string 588 } 589 590 // Error implements the error interface for DisallowedNameError. 591 func (e DisallowedNameError) Error() string { 592 return fmt.Sprintf("Cannot create \"%s\" because it is a disallowed name", 593 e.name) 594 } 595 596 // NameTooLongError indicates that the user tried to write a directory 597 // entry name that would be bigger than KBFS's supported size. 598 type NameTooLongError struct { 599 name string 600 maxAllowedBytes uint32 601 } 602 603 // Error implements the error interface for NameTooLongError. 604 func (e NameTooLongError) Error() string { 605 return fmt.Sprintf("New directory entry name %s has more than the maximum "+ 606 "allowed number of bytes (%d)", e.name, e.maxAllowedBytes) 607 } 608 609 // NoCurrentSessionExpectedError is the error text that will get 610 // converted into a NoCurrentSessionError. 611 var NoCurrentSessionExpectedError = "no current session" 612 613 // RekeyPermissionError indicates that the user tried to rekey a 614 // top-level folder in a manner inconsistent with their permissions. 615 type RekeyPermissionError struct { 616 User kbname.NormalizedUsername 617 Dir string 618 } 619 620 // Error implements the error interface for RekeyPermissionError 621 func (e RekeyPermissionError) Error() string { 622 return fmt.Sprintf("%s is trying to rekey directory %s in a manner "+ 623 "inconsistent with their role", e.User, e.Dir) 624 } 625 626 // NewRekeyPermissionError constructs a RekeyPermissionError for the given 627 // directory and user. 628 func NewRekeyPermissionError( 629 dir *tlfhandle.Handle, username kbname.NormalizedUsername) error { 630 dirname := dir.GetCanonicalPath() 631 return RekeyPermissionError{username, dirname} 632 } 633 634 // RekeyIncompleteError is returned when a rekey is partially done but 635 // needs a writer to finish it. 636 type RekeyIncompleteError struct{} 637 638 func (e RekeyIncompleteError) Error() string { 639 return "Rekey did not complete due to insufficient user permissions" 640 } 641 642 // TimeoutError is just a replacement for context.DeadlineExceeded 643 // with a more friendly error string. 644 type TimeoutError struct { 645 } 646 647 func (e TimeoutError) Error() string { 648 return "Operation timed out" 649 } 650 651 // InvalidOpError is returned when an operation is called that isn't supported 652 // by the current implementation. 653 type InvalidOpError struct { 654 op string 655 } 656 657 func (e InvalidOpError) Error() string { 658 return fmt.Sprintf("Invalid operation: %s", e.op) 659 } 660 661 // NoSuchFolderListError indicates that the user tried to access a 662 // subdirectory of /keybase that doesn't exist. 663 type NoSuchFolderListError struct { 664 Name string 665 NameToLog string 666 PrivName string 667 PubName string 668 } 669 670 // Error implements the error interface for NoSuchFolderListError 671 func (e NoSuchFolderListError) Error() string { 672 return fmt.Sprintf("/keybase/%s is not a Keybase folder. "+ 673 "All folders begin with /keybase/%s or /keybase/%s.", 674 e.NameToLog, e.PrivName, e.PubName) 675 } 676 677 // UnexpectedUnmergedPutError indicates that we tried to do an 678 // unmerged put when that was disallowed. 679 type UnexpectedUnmergedPutError struct { 680 } 681 682 // Error implements the error interface for UnexpectedUnmergedPutError 683 func (e UnexpectedUnmergedPutError) Error() string { 684 return "Unmerged puts are not allowed" 685 } 686 687 // NoSuchTlfHandleError indicates we were unable to resolve a folder 688 // ID to a folder handle. 689 type NoSuchTlfHandleError struct { 690 ID tlf.ID 691 } 692 693 // Error implements the error interface for NoSuchTlfHandleError 694 func (e NoSuchTlfHandleError) Error() string { 695 return fmt.Sprintf("Folder handle for %s not found", e.ID) 696 } 697 698 // NoSuchTlfIDError indicates we were unable to resolve a folder 699 // handle to a folder ID. 700 type NoSuchTlfIDError struct { 701 handle *tlfhandle.Handle 702 } 703 704 // Error implements the error interface for NoSuchTlfIDError 705 func (e NoSuchTlfIDError) Error() string { 706 return fmt.Sprintf("Folder ID for %s not found", 707 e.handle.GetCanonicalPath()) 708 } 709 710 // IncompatibleHandleError indicates that somethine tried to update 711 // the head of a TLF with a RootMetadata with an incompatible handle. 712 type IncompatibleHandleError struct { 713 oldName tlf.CanonicalName 714 partiallyResolvedOldName tlf.CanonicalName 715 newName tlf.CanonicalName 716 } 717 718 func (e IncompatibleHandleError) Error() string { 719 return fmt.Sprintf( 720 "old head %q resolves to %q instead of new head %q", 721 e.oldName, e.partiallyResolvedOldName, e.newName) 722 } 723 724 // UnmergedError indicates that fbo is on an unmerged local revision 725 type UnmergedError struct { 726 } 727 728 // Error implements the error interface for UnmergedError. 729 func (e UnmergedError) Error() string { 730 return "fbo is on an unmerged local revision" 731 } 732 733 // ExclOnUnmergedError happens when an operation with O_EXCL set when fbo is on 734 // an unmerged local revision 735 type ExclOnUnmergedError struct { 736 } 737 738 // Error implements the error interface for ExclOnUnmergedError. 739 func (e ExclOnUnmergedError) Error() string { 740 return "an operation with O_EXCL set is called but fbo is on an unmerged local version" 741 } 742 743 // OverQuotaWarning indicates that the user is over their quota, and 744 // is being slowed down by the server. 745 type OverQuotaWarning struct { 746 UsageBytes int64 747 LimitBytes int64 748 } 749 750 // Error implements the error interface for OverQuotaWarning. 751 func (w OverQuotaWarning) Error() string { 752 return fmt.Sprintf("You are using %d bytes, and your plan limits you "+ 753 "to %d bytes. Please delete some data.", w.UsageBytes, w.LimitBytes) 754 } 755 756 // OpsCantHandleFavorite means that folderBranchOps wasn't able to 757 // deal with a favorites request. 758 type OpsCantHandleFavorite struct { 759 Msg string 760 } 761 762 // Error implements the error interface for OpsCantHandleFavorite. 763 func (e OpsCantHandleFavorite) Error() string { 764 return fmt.Sprintf("Couldn't handle the favorite operation: %s", e.Msg) 765 } 766 767 // RekeyConflictError indicates a conflict happened while trying to rekey. 768 type RekeyConflictError struct { 769 Err error 770 } 771 772 // Error implements the error interface for RekeyConflictError. 773 func (e RekeyConflictError) Error() string { 774 return fmt.Sprintf("Conflict during a rekey, not retrying: %v", e.Err) 775 } 776 777 // UnmergedSelfConflictError indicates that we hit a conflict on the 778 // unmerged branch, so a previous MD PutUnmerged we thought had 779 // failed, had actually succeeded. 780 type UnmergedSelfConflictError struct { 781 Err error 782 } 783 784 // Error implements the error interface for UnmergedSelfConflictError. 785 func (e UnmergedSelfConflictError) Error() string { 786 return fmt.Sprintf("Unmerged self conflict: %v", e.Err) 787 } 788 789 // blockNonExistentError is returned when a block doesn't exist. This 790 // is a generic error, suitable for use by non-server types, whereas 791 // kbfsblock.ServerErrorBlockNonExistent is used only by servers. 792 type blockNonExistentError struct { 793 id kbfsblock.ID 794 } 795 796 func (e blockNonExistentError) Error() string { 797 return fmt.Sprintf("block %s does not exist", e.id) 798 } 799 800 // NoMergedMDError indicates that no MDs for this folder have been 801 // created yet. 802 type NoMergedMDError struct { 803 tlf tlf.ID 804 } 805 806 // Error implements the error interface for NoMergedMDError. 807 func (e NoMergedMDError) Error() string { 808 return fmt.Sprintf("No MD yet for TLF %s", e.tlf) 809 } 810 811 // InvalidFavoritesOpError indicates an unknown FavoritesOp has been provided. 812 type InvalidFavoritesOpError struct{} 813 814 // Error implements the error interface for InvalidFavoritesOpError. 815 func (InvalidFavoritesOpError) Error() string { 816 return "invalid FavoritesOp" 817 } 818 819 // DiskCacheClosedError indicates that the disk cache has been 820 // closed, and thus isn't accepting any more operations. 821 type DiskCacheClosedError struct { 822 op string 823 } 824 825 // Error implements the error interface for DiskCacheClosedError. 826 func (e DiskCacheClosedError) Error() string { 827 return fmt.Sprintf("Error performing %s operation: the disk cache is "+ 828 "closed", e.op) 829 } 830 831 // DiskCacheStartingError indicates that the disk cache has not yet started, so 832 // it isn't yet accepting operations. 833 type DiskCacheStartingError struct { 834 op string 835 } 836 837 // Error implements the error interface for DiskCacheStartingError. 838 func (e DiskCacheStartingError) Error() string { 839 return fmt.Sprintf("Error performing %s operation: the disk cache is "+ 840 "still starting", e.op) 841 } 842 843 // NoUpdatesWhileDirtyError indicates that updates aren't being 844 // accepted while a TLF is locally dirty. 845 type NoUpdatesWhileDirtyError struct{} 846 847 // Error implements the error interface for NoUpdatesWhileDirtyError. 848 func (e NoUpdatesWhileDirtyError) Error() string { 849 return "Ignoring MD updates while writes are dirty" 850 } 851 852 // Disk Cache Errors 853 const ( 854 // StatusCodeDiskBlockCacheError is a generic disk cache error. 855 StatusCodeDiskBlockCacheError = 0x666 856 // StatusCodeDiskMDCacheError is a generic disk cache error. 857 StatusCodeDiskMDCacheError = 0x667 858 // StatusCodeDiskQuotaCacheError is a generic disk cache error. 859 StatusCodeDiskQuotaCacheError = 0x668 860 ) 861 862 // DiskBlockCacheError is a generic disk cache error. 863 type DiskBlockCacheError struct { 864 Msg string 865 } 866 867 func newDiskBlockCacheError(err error) DiskBlockCacheError { 868 return DiskBlockCacheError{err.Error()} 869 } 870 871 // ToStatus implements the ExportableError interface for DiskBlockCacheError. 872 func (e DiskBlockCacheError) ToStatus() (s keybase1.Status) { 873 s.Code = StatusCodeDiskBlockCacheError 874 s.Name = "DISK_BLOCK_CACHE_ERROR" 875 s.Desc = e.Msg 876 return 877 } 878 879 // Error implements the Error interface for DiskBlockCacheError. 880 func (e DiskBlockCacheError) Error() string { 881 return "DiskBlockCacheError{" + e.Msg + "}" 882 } 883 884 // DiskMDCacheError is a generic disk cache error. 885 type DiskMDCacheError struct { 886 Msg string 887 } 888 889 // ToStatus implements the ExportableError interface for DiskMDCacheError. 890 func (e DiskMDCacheError) ToStatus() (s keybase1.Status) { 891 s.Code = StatusCodeDiskMDCacheError 892 s.Name = "DISK_MD_CACHE_ERROR" 893 s.Desc = e.Msg 894 return 895 } 896 897 // Error implements the Error interface for DiskMDCacheError. 898 func (e DiskMDCacheError) Error() string { 899 return "DiskMDCacheError{" + e.Msg + "}" 900 } 901 902 // DiskQuotaCacheError is a generic disk cache error. 903 type DiskQuotaCacheError struct { 904 Msg string 905 } 906 907 // ToStatus implements the ExportableError interface for DiskQuotaCacheError. 908 func (e DiskQuotaCacheError) ToStatus() (s keybase1.Status) { 909 s.Code = StatusCodeDiskQuotaCacheError 910 s.Name = "DISK_QUOTA_CACHE_ERROR" 911 s.Desc = e.Msg 912 return 913 } 914 915 // Error implements the Error interface for DiskQuotaCacheError. 916 func (e DiskQuotaCacheError) Error() string { 917 return "DiskQuotaCacheError{" + e.Msg + "}" 918 } 919 920 // RevokedDeviceVerificationError indicates that the user is trying to 921 // verify a key that has been revoked. It includes useful information 922 // about the revocation, so the code receiving the error can check if 923 // the device was valid at the time of the data being checked. 924 type RevokedDeviceVerificationError struct { 925 info idutil.RevokedKeyInfo 926 } 927 928 // Error implements the Error interface for RevokedDeviceVerificationError. 929 func (e RevokedDeviceVerificationError) Error() string { 930 return fmt.Sprintf("Device was revoked at time %s, root seqno %d", 931 e.info.Time.Time().Format(time.RFC3339Nano), e.info.MerkleRoot.Seqno) 932 } 933 934 // MDWrittenAfterRevokeError indicates that we failed to verify an MD 935 // revision because it was written after the last valid revision that 936 // the corresponding device could have written. 937 type MDWrittenAfterRevokeError struct { 938 tlfID tlf.ID 939 revBad kbfsmd.Revision 940 revLimit kbfsmd.Revision 941 verifyingKey kbfscrypto.VerifyingKey 942 } 943 944 // Error implements the Error interface for MDWrittenAfterRevokeError. 945 func (e MDWrittenAfterRevokeError) Error() string { 946 return fmt.Sprintf("Failed to verify revision %d of folder %s by key %s; "+ 947 "last valid revision would have been %d", 948 e.revBad, e.tlfID, e.verifyingKey, e.revLimit) 949 } 950 951 // RevGarbageCollectedError indicates that the user is trying to 952 // access a revision that's already been garbage-collected. 953 type RevGarbageCollectedError struct { 954 rev kbfsmd.Revision 955 lastGCRev kbfsmd.Revision 956 } 957 958 // Error implements the Error interface for RevGarbageCollectedError. 959 func (e RevGarbageCollectedError) Error() string { 960 return fmt.Sprintf("Requested revision %d has already been garbage "+ 961 "collected (last GC'd rev=%d)", e.rev, e.lastGCRev) 962 } 963 964 // FolderNotResetOnServer indicates that a folder can't be reset by 965 // the user, because it hasn't yet been reset on the mdserver. 966 type FolderNotResetOnServer struct { 967 h *tlfhandle.Handle 968 } 969 970 // Error implements the Error interface for FolderNotResetOnServer. 971 func (e FolderNotResetOnServer) Error() string { 972 return fmt.Sprintf("Folder %s is not yet reset on the server; "+ 973 "contact Keybase for help", e.h.GetCanonicalPath()) 974 } 975 976 // OfflineArchivedError indicates trying to access archived data while 977 // offline. 978 type OfflineArchivedError struct { 979 h *tlfhandle.Handle 980 } 981 982 // Error implements the Error interface for OfflineArchivedError. 983 func (e OfflineArchivedError) Error() string { 984 return fmt.Sprintf("Archived data from %s is not available while offline", 985 e.h.GetCanonicalPath()) 986 } 987 988 // OfflineUnsyncedError indicates trying to access unsynced data while 989 // offline. 990 type OfflineUnsyncedError struct { 991 h *tlfhandle.Handle 992 } 993 994 // Error implements the Error interface for OfflineUnsyncedError. 995 func (e OfflineUnsyncedError) Error() string { 996 return fmt.Sprintf("Unsynced data from %s is not available while offline", 997 e.h.GetCanonicalPath()) 998 } 999 1000 // NextMDNotCachedError indicates we haven't cached the next MD after 1001 // the given Merkle seqno. 1002 type NextMDNotCachedError struct { 1003 TlfID tlf.ID 1004 RootSeqno keybase1.Seqno 1005 } 1006 1007 // Error implements the Error interface for NextMDNotCachedError. 1008 func (e NextMDNotCachedError) Error() string { 1009 return fmt.Sprintf("The MD following %d for folder %s is not cached", 1010 e.RootSeqno, e.TlfID) 1011 } 1012 1013 // DiskCacheTooFullForBlockError indicates that the disk cache is too 1014 // full to fetch a block requested with the `StopIfFull` action type. 1015 type DiskCacheTooFullForBlockError struct { 1016 Ptr data.BlockPointer 1017 Action BlockRequestAction 1018 } 1019 1020 // Error implements the Error interface for DiskCacheTooFullForBlockError. 1021 func (e DiskCacheTooFullForBlockError) Error() string { 1022 return fmt.Sprintf( 1023 "Disk cache too full for block %s requested with action %s", 1024 e.Ptr, e.Action) 1025 } 1026 1027 // NonExistentTeamForHandleError indicates that we're trying to create 1028 // a TLF for a handle that has no corresponding implicit team yet. 1029 // Likely a writer needs to create the implicit team first. 1030 type NonExistentTeamForHandleError struct { 1031 h *tlfhandle.Handle 1032 } 1033 1034 // Error implements the Error interface for NonExistentTeamForHandleError. 1035 func (e NonExistentTeamForHandleError) Error() string { 1036 return fmt.Sprintf("Can't create TLF ID for non-team-backed handle %s", 1037 e.h.GetCanonicalPath()) 1038 }