15
14
# along with this program; if not, write to the Free Software
16
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
__copyright__ = "Copyright (C) 2005 Canonical Ltd."
20
__author__ = "Martin Pool <mbp@canonical.com>"
23
######################################################################
17
"""Exceptions for bzr, and reporting of them.
19
Exceptions are caught at a high level to report errors to the user, and
20
might also be caught inside the program. Therefore it needs to be
21
possible to convert them to a meaningful string, and also for them to be
22
interrogated by the program.
24
Exceptions are defined such that the arguments given to the constructor
25
are stored in the object as properties of the same name. When the
26
object is printed as a string, the doc string of the class is used as
27
a format string with the property dictionary available to it.
29
This means that exceptions can used like this:
33
... raise NotBranchError(path='/foo/bar')
35
... print sys.exc_type
36
... print sys.exc_value
37
... path = getattr(sys.exc_value, 'path', None)
38
... if path is not None:
40
bzrlib.errors.NotBranchError
41
Not a branch: /foo/bar
46
* create a new exception class for any class of error that can be
47
usefully distinguished.
49
* the printable form of an exception is generated by the base class
52
Exception strings should start with a capital letter and not have a final
56
from warnings import warn
58
# based on Scott James Remnant's hct error classes
60
# TODO: is there any value in providing the .args field used by standard
61
# python exceptions? A list of values with no names seems less useful
64
# TODO: Perhaps convert the exception to a string at the moment it's
65
# constructed to make sure it will succeed. But that says nothing about
66
# exceptions that are never raised.
68
# TODO: Convert all the other error classes here to BzrNewError, and eliminate
71
# TODO: The pattern (from hct) of using classes docstrings as message
72
# templates is cute but maybe not such a great idea - perhaps should have a
73
# separate static message_template.
25
76
class BzrError(StandardError):
28
class BzrCheckError(BzrError):
34
def bailout(msg, explanation=[]):
35
ex = BzrError(msg, explanation)
37
trace._tracefile.write('* raising %s\n' % ex)
78
# XXX: Should we show the exception class in
79
# exceptions that don't provide their own message?
80
# maybe it should be done at a higher level
81
## n = self.__class__.__name__ + ': '
83
if len(self.args) == 1:
84
return str(self.args[0])
85
elif len(self.args) == 2:
86
# further explanation or suggestions
88
return n + '\n '.join([self.args[0]] + self.args[1])
90
return n + "%r" % self
92
return n + `self.args`
95
class BzrNewError(BzrError):
97
# base classes should override the docstring with their human-
98
# readable explanation
100
def __init__(self, **kwds):
101
for key, value in kwds.items():
102
setattr(self, key, value)
106
return self.__doc__ % self.__dict__
107
except (NameError, ValueError, KeyError), e:
108
return 'Unprintable exception %s: %s' \
109
% (self.__class__.__name__, str(e))
112
class BzrCheckError(BzrNewError):
113
"""Internal check failed: %(message)s"""
115
def __init__(self, message):
116
BzrNewError.__init__(self)
117
self.message = message
120
class InvalidEntryName(BzrNewError):
121
"""Invalid entry name: %(name)s"""
122
def __init__(self, name):
123
BzrNewError.__init__(self)
127
class InvalidRevisionNumber(BzrNewError):
128
"""Invalid revision number %(revno)d"""
129
def __init__(self, revno):
130
BzrNewError.__init__(self)
134
class InvalidRevisionId(BzrNewError):
135
"""Invalid revision-id {%(revision_id)s} in %(branch)s"""
136
def __init__(self, revision_id, branch):
137
# branch can be any string or object with __str__ defined
138
BzrNewError.__init__(self)
139
self.revision_id = revision_id
143
class NoWorkingTree(BzrNewError):
144
"""No WorkingTree exists for %(base)s."""
146
def __init__(self, base):
147
BzrNewError.__init__(self)
151
class NotLocalUrl(BzrNewError):
152
"""%(url)s is not a local path."""
154
def __init__(self, url):
155
BzrNewError.__init__(self)
159
class BzrCommandError(BzrError):
160
# Error from malformed user command
161
# This is being misused as a generic exception
162
# pleae subclass. RBC 20051030
164
# I think it's a waste of effort to differentiate between errors that
165
# are not intended to be caught anyway. UI code need not subclass
166
# BzrCommandError, and non-UI code should not throw a subclass of
167
# BzrCommandError. ADHB 20051211
172
class BzrOptionError(BzrCommandError):
173
"""Some missing or otherwise incorrect option was supplied."""
176
class StrictCommitFailed(Exception):
177
"""Commit refused because there are unknowns in the tree."""
180
# XXX: Should be unified with TransportError; they seem to represent the
182
class PathError(BzrNewError):
183
"""Generic path error: %(path)r%(extra)s)"""
185
def __init__(self, path, extra=None):
186
BzrNewError.__init__(self)
189
self.extra = ': ' + str(extra)
194
class NoSuchFile(PathError):
195
"""No such file: %(path)r%(extra)s"""
198
class FileExists(PathError):
199
"""File exists: %(path)r%(extra)s"""
202
class DirectoryNotEmpty(PathError):
203
"""Directory not empty: %(path)r%(extra)s"""
206
class ResourceBusy(PathError):
207
"""Device or resource busy: %(path)r%(extra)s"""
210
class PermissionDenied(PathError):
211
"""Permission denied: %(path)r%(extra)s"""
214
class PathNotChild(BzrNewError):
215
"""Path %(path)r is not a child of path %(base)r%(extra)s"""
216
def __init__(self, path, base, extra=None):
217
BzrNewError.__init__(self)
221
self.extra = ': ' + str(extra)
226
class NotBranchError(PathError):
227
"""Not a branch: %(path)s"""
230
class AlreadyBranchError(PathError):
231
"""Already a branch: %(path)s."""
234
class BranchExistsWithoutWorkingTree(PathError):
235
"""Directory contains a branch, but no working tree \
236
(use bzr checkout if you wish to build a working tree): %(path)s"""
239
class NoRepositoryPresent(BzrNewError):
240
"""No repository present: %(path)r"""
241
def __init__(self, bzrdir):
242
BzrNewError.__init__(self)
243
self.path = bzrdir.transport.clone('..').base
246
class FileInWrongBranch(BzrNewError):
247
"""File %(path)s in not in branch %(branch_base)s."""
249
def __init__(self, branch, path):
250
BzrNewError.__init__(self)
252
self.branch_base = branch.base
256
class UnsupportedFormatError(BzrError):
257
"""Specified path is a bzr branch that we recognize but cannot read."""
259
return 'unsupported branch format: %s' % self.args[0]
262
class UnknownFormatError(BzrError):
263
"""Specified path is a bzr branch whose format we do not recognize."""
265
return 'unknown branch format: %s' % self.args[0]
268
class IncompatibleFormat(BzrNewError):
269
"""Format %(format)s is not compatible with .bzr version %(bzrdir)s."""
271
def __init__(self, format, bzrdir_format):
272
BzrNewError.__init__(self)
274
self.bzrdir = bzrdir_format
277
class NotVersionedError(BzrNewError):
278
"""%(path)s is not versioned"""
279
def __init__(self, path):
280
BzrNewError.__init__(self)
284
class PathsNotVersionedError(BzrNewError):
285
# used when reporting several paths are not versioned
286
"""Path(s) are not versioned: %(paths_as_string)s"""
288
def __init__(self, paths):
289
from bzrlib.osutils import quotefn
290
BzrNewError.__init__(self)
292
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
295
class PathsDoNotExist(BzrNewError):
296
"""Path(s) do not exist: %(paths_as_string)s"""
298
# used when reporting that paths are neither versioned nor in the working
301
def __init__(self, paths):
303
from bzrlib.osutils import quotefn
304
BzrNewError.__init__(self)
306
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
309
class BadFileKindError(BzrError):
310
"""Specified file is of a kind that cannot be added.
312
(For example a symlink or device file.)"""
315
class ForbiddenFileError(BzrError):
316
"""Cannot operate on a file because it is a control file."""
319
class LockError(BzrNewError):
320
"""Lock error: %(message)s"""
321
# All exceptions from the lock/unlock functions should be from
322
# this exception class. They will be translated as necessary. The
323
# original exception is available as e.original_error
325
# New code should prefer to raise specific subclasses
326
def __init__(self, message):
327
self.message = message
330
class CommitNotPossible(LockError):
331
"""A commit was attempted but we do not have a write lock open."""
336
class AlreadyCommitted(LockError):
337
"""A rollback was requested, but is not able to be accomplished."""
342
class ReadOnlyError(LockError):
343
"""A write attempt was made in a read only transaction on %(obj)s"""
344
def __init__(self, obj):
348
class OutSideTransaction(BzrNewError):
349
"""A transaction related operation was attempted after the transaction finished."""
352
class ObjectNotLocked(LockError):
353
"""%(obj)r is not locked"""
354
# this can indicate that any particular object is not locked; see also
355
# LockNotHeld which means that a particular *lock* object is not held by
356
# the caller -- perhaps they should be unified.
357
def __init__(self, obj):
361
class ReadOnlyObjectDirtiedError(ReadOnlyError):
362
"""Cannot change object %(obj)r in read only transaction"""
363
def __init__(self, obj):
367
class UnlockableTransport(LockError):
368
"""Cannot lock: transport is read only: %(transport)s"""
369
def __init__(self, transport):
370
self.transport = transport
373
class LockContention(LockError):
374
"""Could not acquire lock %(lock)s"""
375
# TODO: show full url for lock, combining the transport and relative bits?
376
def __init__(self, lock):
380
class LockBroken(LockError):
381
"""Lock was broken while still open: %(lock)s - check storage consistency!"""
382
def __init__(self, lock):
386
class LockBreakMismatch(LockError):
387
"""Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"""
388
def __init__(self, lock, holder, target):
394
class LockNotHeld(LockError):
395
"""Lock not held: %(lock)s"""
396
def __init__(self, lock):
400
class PointlessCommit(BzrNewError):
401
"""No changes to commit"""
404
class UpgradeReadonly(BzrNewError):
405
"""Upgrade URL cannot work with readonly URL's."""
408
class UpToDateFormat(BzrNewError):
409
"""The branch format %(format)s is already at the most recent format."""
411
def __init__(self, format):
412
BzrNewError.__init__(self)
417
class StrictCommitFailed(Exception):
418
"""Commit refused because there are unknowns in the tree."""
421
class NoSuchRevision(BzrError):
422
def __init__(self, branch, revision):
424
self.revision = revision
425
msg = "Branch %s has no revision %s" % (branch, revision)
426
BzrError.__init__(self, msg)
429
class HistoryMissing(BzrError):
430
def __init__(self, branch, object_type, object_id):
432
BzrError.__init__(self,
433
'%s is missing %s {%s}'
434
% (branch, object_type, object_id))
437
class DivergedBranches(BzrError):
439
def __init__(self, branch1, branch2):
440
BzrError.__init__(self, "These branches have diverged. Try merge.")
441
self.branch1 = branch1
442
self.branch2 = branch2
445
class UnrelatedBranches(BzrCommandError):
447
msg = "Branches have no common ancestor, and no base revision"\
449
BzrCommandError.__init__(self, msg)
452
class NoCommonAncestor(BzrError):
453
def __init__(self, revision_a, revision_b):
454
msg = "Revisions have no common ancestor: %s %s." \
455
% (revision_a, revision_b)
456
BzrError.__init__(self, msg)
459
class NoCommonRoot(BzrError):
460
def __init__(self, revision_a, revision_b):
461
msg = "Revisions are not derived from the same root: %s %s." \
462
% (revision_a, revision_b)
463
BzrError.__init__(self, msg)
467
class NotAncestor(BzrError):
468
def __init__(self, rev_id, not_ancestor_id):
469
msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id,
471
BzrError.__init__(self, msg)
473
self.not_ancestor_id = not_ancestor_id
476
class InstallFailed(BzrError):
477
def __init__(self, revisions):
478
msg = "Could not install revisions:\n%s" % " ,".join(revisions)
479
BzrError.__init__(self, msg)
480
self.revisions = revisions
483
class AmbiguousBase(BzrError):
484
def __init__(self, bases):
485
warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
487
msg = "The correct base is unclear, becase %s are all equally close" %\
489
BzrError.__init__(self, msg)
493
class NoCommits(BzrError):
494
def __init__(self, branch):
495
msg = "Branch %s has no commits." % branch
496
BzrError.__init__(self, msg)
499
class UnlistableStore(BzrError):
500
def __init__(self, store):
501
BzrError.__init__(self, "Store %s is not listable" % store)
505
class UnlistableBranch(BzrError):
506
def __init__(self, br):
507
BzrError.__init__(self, "Stores for branch %s are not listable" % br)
510
class BoundBranchOutOfDate(BzrNewError):
511
"""Bound branch %(branch)s is out of date with master branch %(master)s."""
512
def __init__(self, branch, master):
513
BzrNewError.__init__(self)
518
class CommitToDoubleBoundBranch(BzrNewError):
519
"""Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
520
def __init__(self, branch, master, remote):
521
BzrNewError.__init__(self)
527
class OverwriteBoundBranch(BzrNewError):
528
"""Cannot pull --overwrite to a branch which is bound %(branch)s"""
529
def __init__(self, branch):
530
BzrNewError.__init__(self)
534
class BoundBranchConnectionFailure(BzrNewError):
535
"""Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
536
def __init__(self, branch, target, error):
537
BzrNewError.__init__(self)
543
class WeaveError(BzrNewError):
544
"""Error in processing weave: %(message)s"""
546
def __init__(self, message=None):
547
BzrNewError.__init__(self)
548
self.message = message
551
class WeaveRevisionAlreadyPresent(WeaveError):
552
"""Revision {%(revision_id)s} already present in %(weave)s"""
553
def __init__(self, revision_id, weave):
555
WeaveError.__init__(self)
556
self.revision_id = revision_id
560
class WeaveRevisionNotPresent(WeaveError):
561
"""Revision {%(revision_id)s} not present in %(weave)s"""
563
def __init__(self, revision_id, weave):
564
WeaveError.__init__(self)
565
self.revision_id = revision_id
569
class WeaveFormatError(WeaveError):
570
"""Weave invariant violated: %(what)s"""
572
def __init__(self, what):
573
WeaveError.__init__(self)
577
class WeaveParentMismatch(WeaveError):
578
"""Parents are mismatched between two revisions."""
581
class WeaveInvalidChecksum(WeaveError):
582
"""Text did not match it's checksum: %(message)s"""
585
class WeaveTextDiffers(WeaveError):
586
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
588
def __init__(self, revision_id, weave_a, weave_b):
589
WeaveError.__init__(self)
590
self.revision_id = revision_id
591
self.weave_a = weave_a
592
self.weave_b = weave_b
595
class WeaveTextDiffers(WeaveError):
596
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
598
def __init__(self, revision_id, weave_a, weave_b):
599
WeaveError.__init__(self)
600
self.revision_id = revision_id
601
self.weave_a = weave_a
602
self.weave_b = weave_b
605
class VersionedFileError(BzrNewError):
606
"""Versioned file error."""
609
class RevisionNotPresent(VersionedFileError):
610
"""Revision {%(revision_id)s} not present in %(file_id)s."""
612
def __init__(self, revision_id, file_id):
613
VersionedFileError.__init__(self)
614
self.revision_id = revision_id
615
self.file_id = file_id
618
class RevisionAlreadyPresent(VersionedFileError):
619
"""Revision {%(revision_id)s} already present in %(file_id)s."""
621
def __init__(self, revision_id, file_id):
622
VersionedFileError.__init__(self)
623
self.revision_id = revision_id
624
self.file_id = file_id
627
class KnitError(BzrNewError):
631
class KnitHeaderError(KnitError):
632
"""Knit header error: %(badline)r unexpected"""
634
def __init__(self, badline):
635
KnitError.__init__(self)
636
self.badline = badline
639
class KnitCorrupt(KnitError):
640
"""Knit %(filename)s corrupt: %(how)s"""
642
def __init__(self, filename, how):
643
KnitError.__init__(self)
644
self.filename = filename
648
class NoSuchExportFormat(BzrNewError):
649
"""Export format %(format)r not supported"""
650
def __init__(self, format):
651
BzrNewError.__init__(self)
655
class TransportError(BzrError):
656
"""All errors thrown by Transport implementations should derive
659
def __init__(self, msg=None, orig_error=None):
660
if msg is None and orig_error is not None:
661
msg = str(orig_error)
662
BzrError.__init__(self, msg)
664
self.orig_error = orig_error
667
# A set of semi-meaningful errors which can be thrown
668
class TransportNotPossible(TransportError):
669
"""This is for transports where a specific function is explicitly not
670
possible. Such as pushing files to an HTTP server.
675
class ConnectionError(TransportError):
676
"""A connection problem prevents file retrieval.
677
This does not indicate whether the file exists or not; it indicates that a
678
precondition for requesting the file was not met.
680
def __init__(self, msg=None, orig_error=None):
681
TransportError.__init__(self, msg=msg, orig_error=orig_error)
684
class ConnectionReset(TransportError):
685
"""The connection has been closed."""
689
class ConflictsInTree(BzrError):
691
BzrError.__init__(self, "Working tree has conflicts.")
694
class ParseConfigError(BzrError):
695
def __init__(self, errors, filename):
698
message = "Error(s) parsing config file %s:\n%s" % \
699
(filename, ('\n'.join(e.message for e in errors)))
700
BzrError.__init__(self, message)
703
class SigningFailed(BzrError):
704
def __init__(self, command_line):
705
BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
709
class WorkingTreeNotRevision(BzrError):
710
def __init__(self, tree):
711
BzrError.__init__(self, "The working tree for %s has changed since"
712
" last commit, but weave merge requires that it be"
713
" unchanged." % tree.basedir)
716
class CantReprocessAndShowBase(BzrNewError):
717
"""Can't reprocess and show base.
718
Reprocessing obscures relationship of conflicting lines to base."""
721
class GraphCycleError(BzrNewError):
722
"""Cycle in graph %(graph)r"""
723
def __init__(self, graph):
724
BzrNewError.__init__(self)
728
class NotConflicted(BzrNewError):
729
"""File %(filename)s is not conflicted."""
731
def __init__(self, filename):
732
BzrNewError.__init__(self)
733
self.filename = filename
736
class MustUseDecorated(Exception):
737
"""A decorating function has requested its original command be used.
739
This should never escape bzr, so does not need to be printable.
743
class MissingText(BzrNewError):
744
"""Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
746
def __init__(self, branch, text_revision, file_id):
747
BzrNewError.__init__(self)
749
self.base = branch.base
750
self.text_revision = text_revision
751
self.file_id = file_id
754
class DuplicateKey(BzrNewError):
755
"""Key %(key)s is already present in map"""
758
class MalformedTransform(BzrNewError):
759
"""Tree transform is malformed %(conflicts)r"""
762
class BzrBadParameter(BzrNewError):
763
"""A bad parameter : %(param)s is not usable.
765
This exception should never be thrown, but it is a base class for all
766
parameter-to-function errors.
768
def __init__(self, param):
769
BzrNewError.__init__(self)
773
class BzrBadParameterNotUnicode(BzrBadParameter):
774
"""Parameter %(param)s is neither unicode nor utf8."""
777
class ReusingTransform(BzrNewError):
778
"""Attempt to reuse a transform that has already been applied."""
781
class CantMoveRoot(BzrNewError):
782
"""Moving the root directory is not supported at this time"""
785
class BzrBadParameterNotString(BzrBadParameter):
786
"""Parameter %(param)s is not a string or unicode string."""
789
class BzrBadParameterMissing(BzrBadParameter):
790
"""Parameter $(param)s is required but not present."""
793
class BzrBadParameterUnicode(BzrBadParameter):
794
"""Parameter %(param)s is unicode but only byte-strings are permitted."""
797
class BzrBadParameterContainsNewline(BzrBadParameter):
798
"""Parameter %(param)s contains a newline."""
801
class DependencyNotPresent(BzrNewError):
802
"""Unable to import library "%(library)s": %(error)s"""
804
def __init__(self, library, error):
805
BzrNewError.__init__(self, library=library, error=error)
808
class ParamikoNotPresent(DependencyNotPresent):
809
"""Unable to import paramiko (required for sftp support): %(error)s"""
811
def __init__(self, error):
812
DependencyNotPresent.__init__(self, 'paramiko', error)
815
class UninitializableFormat(BzrNewError):
816
"""Format %(format)s cannot be initialised by this version of bzr."""
818
def __init__(self, format):
819
BzrNewError.__init__(self)
823
class NoDiff3(BzrNewError):
824
"""Diff3 is not installed on this machine."""
827
class ExistingLimbo(BzrNewError):
828
"""This tree contains left-over files from a failed operation.
829
Please examine %(limbo_dir)s to see if it contains any files you wish to
830
keep, and delete it when you are done.
832
def __init__(self, limbo_dir):
833
BzrNewError.__init__(self)
834
self.limbo_dir = limbo_dir
837
class ImmortalLimbo(BzrNewError):
838
"""Unable to delete transform temporary directory $(limbo_dir)s.
839
Please examine %(limbo_dir)s to see if it contains any files you wish to
840
keep, and delete it when you are done.
842
def __init__(self, limbo_dir):
843
BzrNewError.__init__(self)
844
self.limbo_dir = limbo_dir
847
class OutOfDateTree(BzrNewError):
848
"""Working tree is out of date, please run 'bzr update'."""
850
def __init__(self, tree):
851
BzrNewError.__init__(self)
855
class MergeModifiedFormatError(BzrNewError):
856
"""Error in merge modified format"""
859
class ConflictFormatError(BzrNewError):
860
"""Format error in conflict listings"""
863
class CorruptRepository(BzrNewError):
864
"""An error has been detected in the repository %(repo_path)s.
865
Please run bzr reconcile on this repository."""
867
def __init__(self, repo):
868
BzrNewError.__init__(self)
869
self.repo_path = repo.bzrdir.root_transport.base
872
class UpgradeRequired(BzrNewError):
873
"""To use this feature you must upgrade your branch at %(path)s."""
875
def __init__(self, path):
876
BzrNewError.__init__(self)
880
class LocalRequiresBoundBranch(BzrNewError):
881
"""Cannot perform local-only commits on unbound branches."""
884
class MissingProgressBarFinish(BzrNewError):
885
"""A nested progress bar was not 'finished' correctly."""
888
class UnsupportedOperation(BzrNewError):
889
"""The method %(mname)s is not supported on objects of type %(tname)s."""
890
def __init__(self, method, method_self):
892
self.mname = method.__name__
893
self.tname = type(method_self).__name__
896
class BinaryFile(BzrNewError):
897
"""File is binary but should be text."""
900
class IllegalPath(BzrNewError):
901
"""The path %(path)s is not permitted on this platform"""
903
def __init__(self, path):
904
BzrNewError.__init__(self)