14
15
# along with this program; if not, write to the Free Software
15
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
from bzrlib.patches import (PatchSyntax,
65
# based on Scott James Remnant's hct error classes
67
# TODO: is there any value in providing the .args field used by standard
68
# python exceptions? A list of values with no names seems less useful
71
# TODO: Perhaps convert the exception to a string at the moment it's
72
# constructed to make sure it will succeed. But that says nothing about
73
# exceptions that are never raised.
75
# TODO: Convert all the other error classes here to BzrNewError, and eliminate
78
# TODO: The pattern (from hct) of using classes docstrings as message
79
# templates is cute but maybe not such a great idea - perhaps should have a
80
# separate static message_template.
19
__copyright__ = "Copyright (C) 2005 Canonical Ltd."
20
__author__ = "Martin Pool <mbp@canonical.com>"
23
######################################################################
83
25
class BzrError(StandardError):
85
# XXX: Should we show the exception class in
86
# exceptions that don't provide their own message?
87
# maybe it should be done at a higher level
88
## n = self.__class__.__name__ + ': '
90
if len(self.args) == 1:
91
return str(self.args[0])
92
elif len(self.args) == 2:
93
# further explanation or suggestions
95
return n + '\n '.join([self.args[0]] + self.args[1])
97
return n + "%r" % self
99
return n + `self.args`
102
class BzrNewError(BzrError):
104
# base classes should override the docstring with their human-
105
# readable explanation
107
def __init__(self, **kwds):
108
for key, value in kwds.items():
109
setattr(self, key, value)
113
return self.__doc__ % self.__dict__
114
except (NameError, ValueError, KeyError), e:
115
return 'Unprintable exception %s: %s' \
116
% (self.__class__.__name__, str(e))
119
class BzrCheckError(BzrNewError):
120
"""Internal check failed: %(message)s"""
122
def __init__(self, message):
123
BzrNewError.__init__(self)
124
self.message = message
127
class InvalidEntryName(BzrNewError):
128
"""Invalid entry name: %(name)s"""
129
def __init__(self, name):
130
BzrNewError.__init__(self)
134
class InvalidRevisionNumber(BzrNewError):
135
"""Invalid revision number %(revno)d"""
136
def __init__(self, revno):
137
BzrNewError.__init__(self)
141
class InvalidRevisionId(BzrNewError):
142
"""Invalid revision-id {%(revision_id)s} in %(branch)s"""
143
def __init__(self, revision_id, branch):
144
# branch can be any string or object with __str__ defined
145
BzrNewError.__init__(self)
146
self.revision_id = revision_id
150
class NoWorkingTree(BzrNewError):
151
"""No WorkingTree exists for %(base)s."""
153
def __init__(self, base):
154
BzrNewError.__init__(self)
158
class NotLocalUrl(BzrNewError):
159
"""%(url)s is not a local path."""
161
def __init__(self, url):
162
BzrNewError.__init__(self)
28
class BzrCheckError(BzrError):
166
32
class BzrCommandError(BzrError):
167
33
# Error from malformed user command
168
# This is being misused as a generic exception
169
# pleae subclass. RBC 20051030
171
# I think it's a waste of effort to differentiate between errors that
172
# are not intended to be caught anyway. UI code need not subclass
173
# BzrCommandError, and non-UI code should not throw a subclass of
174
# BzrCommandError. ADHB 20051211
179
class BzrOptionError(BzrCommandError):
180
"""Some missing or otherwise incorrect option was supplied."""
183
class StrictCommitFailed(Exception):
184
"""Commit refused because there are unknowns in the tree."""
187
# XXX: Should be unified with TransportError; they seem to represent the
189
class PathError(BzrNewError):
190
"""Generic path error: %(path)r%(extra)s)"""
192
def __init__(self, path, extra=None):
193
BzrNewError.__init__(self)
196
self.extra = ': ' + str(extra)
201
class NoSuchFile(PathError):
202
"""No such file: %(path)r%(extra)s"""
205
class FileExists(PathError):
206
"""File exists: %(path)r%(extra)s"""
209
class DirectoryNotEmpty(PathError):
210
"""Directory not empty: %(path)r%(extra)s"""
213
class ResourceBusy(PathError):
214
"""Device or resource busy: %(path)r%(extra)s"""
217
class PermissionDenied(PathError):
218
"""Permission denied: %(path)r%(extra)s"""
221
class PathNotChild(BzrNewError):
222
"""Path %(path)r is not a child of path %(base)r%(extra)s"""
223
def __init__(self, path, base, extra=None):
224
BzrNewError.__init__(self)
228
self.extra = ': ' + str(extra)
233
class NotBranchError(PathError):
234
"""Not a branch: %(path)s"""
237
class AlreadyBranchError(PathError):
238
"""Already a branch: %(path)s."""
241
class BranchExistsWithoutWorkingTree(PathError):
242
"""Directory contains a branch, but no working tree \
243
(use bzr checkout if you wish to build a working tree): %(path)s"""
246
class NoRepositoryPresent(BzrNewError):
247
"""No repository present: %(path)r"""
248
def __init__(self, bzrdir):
249
BzrNewError.__init__(self)
250
self.path = bzrdir.transport.clone('..').base
253
class FileInWrongBranch(BzrNewError):
254
"""File %(path)s in not in branch %(branch_base)s."""
256
def __init__(self, branch, path):
257
BzrNewError.__init__(self)
259
self.branch_base = branch.base
263
class UnsupportedFormatError(BzrError):
264
"""Specified path is a bzr branch that we recognize but cannot read."""
266
return 'unsupported branch format: %s' % self.args[0]
269
class UnknownFormatError(BzrError):
270
"""Specified path is a bzr branch whose format we do not recognize."""
272
return 'unknown branch format: %s' % self.args[0]
275
class IncompatibleFormat(BzrNewError):
276
"""Format %(format)s is not compatible with .bzr version %(bzrdir)s."""
278
def __init__(self, format, bzrdir_format):
279
BzrNewError.__init__(self)
281
self.bzrdir = bzrdir_format
284
class NotVersionedError(BzrNewError):
285
"""%(path)s is not versioned"""
286
def __init__(self, path):
287
BzrNewError.__init__(self)
291
class PathsNotVersionedError(BzrNewError):
292
# used when reporting several paths are not versioned
293
"""Path(s) are not versioned: %(paths_as_string)s"""
295
def __init__(self, paths):
296
from bzrlib.osutils import quotefn
297
BzrNewError.__init__(self)
299
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
302
class PathsDoNotExist(BzrNewError):
303
"""Path(s) do not exist: %(paths_as_string)s"""
305
# used when reporting that paths are neither versioned nor in the working
308
def __init__(self, paths):
310
from bzrlib.osutils import quotefn
311
BzrNewError.__init__(self)
313
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
316
class BadFileKindError(BzrError):
317
"""Specified file is of a kind that cannot be added.
319
(For example a symlink or device file.)"""
322
class ForbiddenFileError(BzrError):
323
"""Cannot operate on a file because it is a control file."""
326
class LockError(BzrNewError):
327
"""Lock error: %(message)s"""
328
# All exceptions from the lock/unlock functions should be from
329
# this exception class. They will be translated as necessary. The
330
# original exception is available as e.original_error
332
# New code should prefer to raise specific subclasses
333
def __init__(self, message):
334
self.message = message
337
class CommitNotPossible(LockError):
338
"""A commit was attempted but we do not have a write lock open."""
343
class AlreadyCommitted(LockError):
344
"""A rollback was requested, but is not able to be accomplished."""
349
class ReadOnlyError(LockError):
350
"""A write attempt was made in a read only transaction on %(obj)s"""
351
def __init__(self, obj):
355
class OutSideTransaction(BzrNewError):
356
"""A transaction related operation was attempted after the transaction finished."""
359
class ObjectNotLocked(LockError):
360
"""%(obj)r is not locked"""
361
# this can indicate that any particular object is not locked; see also
362
# LockNotHeld which means that a particular *lock* object is not held by
363
# the caller -- perhaps they should be unified.
364
def __init__(self, obj):
368
class ReadOnlyObjectDirtiedError(ReadOnlyError):
369
"""Cannot change object %(obj)r in read only transaction"""
370
def __init__(self, obj):
374
class UnlockableTransport(LockError):
375
"""Cannot lock: transport is read only: %(transport)s"""
376
def __init__(self, transport):
377
self.transport = transport
380
class LockContention(LockError):
381
"""Could not acquire lock %(lock)s"""
382
# TODO: show full url for lock, combining the transport and relative bits?
383
def __init__(self, lock):
387
class LockBroken(LockError):
388
"""Lock was broken while still open: %(lock)s - check storage consistency!"""
389
def __init__(self, lock):
393
class LockBreakMismatch(LockError):
394
"""Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"""
395
def __init__(self, lock, holder, target):
401
class LockNotHeld(LockError):
402
"""Lock not held: %(lock)s"""
403
def __init__(self, lock):
407
class PointlessCommit(BzrNewError):
408
"""No changes to commit"""
411
class UpgradeReadonly(BzrNewError):
412
"""Upgrade URL cannot work with readonly URL's."""
415
class UpToDateFormat(BzrNewError):
416
"""The branch format %(format)s is already at the most recent format."""
418
def __init__(self, format):
419
BzrNewError.__init__(self)
424
class StrictCommitFailed(Exception):
425
"""Commit refused because there are unknowns in the tree."""
428
class NoSuchRevision(BzrError):
429
def __init__(self, branch, revision):
431
self.revision = revision
432
msg = "Branch %s has no revision %s" % (branch, revision)
433
BzrError.__init__(self, msg)
436
class HistoryMissing(BzrError):
437
def __init__(self, branch, object_type, object_id):
439
BzrError.__init__(self,
440
'%s is missing %s {%s}'
441
% (branch, object_type, object_id))
444
class DivergedBranches(BzrError):
446
def __init__(self, branch1, branch2):
447
BzrError.__init__(self, "These branches have diverged. Try merge.")
448
self.branch1 = branch1
449
self.branch2 = branch2
452
class UnrelatedBranches(BzrCommandError):
454
msg = "Branches have no common ancestor, and no base revision"\
456
BzrCommandError.__init__(self, msg)
459
class NoCommonAncestor(BzrError):
460
def __init__(self, revision_a, revision_b):
461
msg = "Revisions have no common ancestor: %s %s." \
462
% (revision_a, revision_b)
463
BzrError.__init__(self, msg)
466
class NoCommonRoot(BzrError):
467
def __init__(self, revision_a, revision_b):
468
msg = "Revisions are not derived from the same root: %s %s." \
469
% (revision_a, revision_b)
470
BzrError.__init__(self, msg)
474
class NotAncestor(BzrError):
475
def __init__(self, rev_id, not_ancestor_id):
476
msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id,
478
BzrError.__init__(self, msg)
480
self.not_ancestor_id = not_ancestor_id
483
class InstallFailed(BzrError):
484
def __init__(self, revisions):
485
msg = "Could not install revisions:\n%s" % " ,".join(revisions)
486
BzrError.__init__(self, msg)
487
self.revisions = revisions
490
class AmbiguousBase(BzrError):
491
def __init__(self, bases):
492
warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
494
msg = "The correct base is unclear, becase %s are all equally close" %\
496
BzrError.__init__(self, msg)
500
class NoCommits(BzrError):
501
def __init__(self, branch):
502
msg = "Branch %s has no commits." % branch
503
BzrError.__init__(self, msg)
506
class UnlistableStore(BzrError):
507
def __init__(self, store):
508
BzrError.__init__(self, "Store %s is not listable" % store)
512
class UnlistableBranch(BzrError):
513
def __init__(self, br):
514
BzrError.__init__(self, "Stores for branch %s are not listable" % br)
517
class BoundBranchOutOfDate(BzrNewError):
518
"""Bound branch %(branch)s is out of date with master branch %(master)s."""
519
def __init__(self, branch, master):
520
BzrNewError.__init__(self)
525
class CommitToDoubleBoundBranch(BzrNewError):
526
"""Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
527
def __init__(self, branch, master, remote):
528
BzrNewError.__init__(self)
534
class OverwriteBoundBranch(BzrNewError):
535
"""Cannot pull --overwrite to a branch which is bound %(branch)s"""
536
def __init__(self, branch):
537
BzrNewError.__init__(self)
541
class BoundBranchConnectionFailure(BzrNewError):
542
"""Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
543
def __init__(self, branch, target, error):
544
BzrNewError.__init__(self)
550
class WeaveError(BzrNewError):
551
"""Error in processing weave: %(message)s"""
553
def __init__(self, message=None):
554
BzrNewError.__init__(self)
555
self.message = message
558
class WeaveRevisionAlreadyPresent(WeaveError):
559
"""Revision {%(revision_id)s} already present in %(weave)s"""
560
def __init__(self, revision_id, weave):
562
WeaveError.__init__(self)
563
self.revision_id = revision_id
567
class WeaveRevisionNotPresent(WeaveError):
568
"""Revision {%(revision_id)s} not present in %(weave)s"""
570
def __init__(self, revision_id, weave):
571
WeaveError.__init__(self)
572
self.revision_id = revision_id
576
class WeaveFormatError(WeaveError):
577
"""Weave invariant violated: %(what)s"""
579
def __init__(self, what):
580
WeaveError.__init__(self)
584
class WeaveParentMismatch(WeaveError):
585
"""Parents are mismatched between two revisions."""
588
class WeaveInvalidChecksum(WeaveError):
589
"""Text did not match it's checksum: %(message)s"""
592
class WeaveTextDiffers(WeaveError):
593
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
595
def __init__(self, revision_id, weave_a, weave_b):
596
WeaveError.__init__(self)
597
self.revision_id = revision_id
598
self.weave_a = weave_a
599
self.weave_b = weave_b
602
class WeaveTextDiffers(WeaveError):
603
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
605
def __init__(self, revision_id, weave_a, weave_b):
606
WeaveError.__init__(self)
607
self.revision_id = revision_id
608
self.weave_a = weave_a
609
self.weave_b = weave_b
612
class VersionedFileError(BzrNewError):
613
"""Versioned file error."""
616
class RevisionNotPresent(VersionedFileError):
617
"""Revision {%(revision_id)s} not present in %(file_id)s."""
619
def __init__(self, revision_id, file_id):
620
VersionedFileError.__init__(self)
621
self.revision_id = revision_id
622
self.file_id = file_id
625
class RevisionAlreadyPresent(VersionedFileError):
626
"""Revision {%(revision_id)s} already present in %(file_id)s."""
628
def __init__(self, revision_id, file_id):
629
VersionedFileError.__init__(self)
630
self.revision_id = revision_id
631
self.file_id = file_id
634
class KnitError(BzrNewError):
638
class KnitHeaderError(KnitError):
639
"""Knit header error: %(badline)r unexpected"""
641
def __init__(self, badline):
642
KnitError.__init__(self)
643
self.badline = badline
646
class KnitCorrupt(KnitError):
647
"""Knit %(filename)s corrupt: %(how)s"""
649
def __init__(self, filename, how):
650
KnitError.__init__(self)
651
self.filename = filename
655
class NoSuchExportFormat(BzrNewError):
656
"""Export format %(format)r not supported"""
657
def __init__(self, format):
658
BzrNewError.__init__(self)
662
class TransportError(BzrError):
663
"""All errors thrown by Transport implementations should derive
666
def __init__(self, msg=None, orig_error=None):
667
if msg is None and orig_error is not None:
668
msg = str(orig_error)
669
BzrError.__init__(self, msg)
671
self.orig_error = orig_error
674
# A set of semi-meaningful errors which can be thrown
675
class TransportNotPossible(TransportError):
676
"""This is for transports where a specific function is explicitly not
677
possible. Such as pushing files to an HTTP server.
682
class ConnectionError(TransportError):
683
"""A connection problem prevents file retrieval.
684
This does not indicate whether the file exists or not; it indicates that a
685
precondition for requesting the file was not met.
687
def __init__(self, msg=None, orig_error=None):
688
TransportError.__init__(self, msg=msg, orig_error=orig_error)
691
class ConnectionReset(TransportError):
692
"""The connection has been closed."""
696
class ConflictsInTree(BzrError):
698
BzrError.__init__(self, "Working tree has conflicts.")
701
class ParseConfigError(BzrError):
702
def __init__(self, errors, filename):
705
message = "Error(s) parsing config file %s:\n%s" % \
706
(filename, ('\n'.join(e.message for e in errors)))
707
BzrError.__init__(self, message)
710
class SigningFailed(BzrError):
711
def __init__(self, command_line):
712
BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
716
class WorkingTreeNotRevision(BzrError):
717
def __init__(self, tree):
718
BzrError.__init__(self, "The working tree for %s has changed since"
719
" last commit, but weave merge requires that it be"
720
" unchanged." % tree.basedir)
723
class CantReprocessAndShowBase(BzrNewError):
724
"""Can't reprocess and show base.
725
Reprocessing obscures relationship of conflicting lines to base."""
728
class GraphCycleError(BzrNewError):
729
"""Cycle in graph %(graph)r"""
730
def __init__(self, graph):
731
BzrNewError.__init__(self)
735
class NotConflicted(BzrNewError):
736
"""File %(filename)s is not conflicted."""
738
def __init__(self, filename):
739
BzrNewError.__init__(self)
740
self.filename = filename
743
class MustUseDecorated(Exception):
744
"""A decorating function has requested its original command be used.
746
This should never escape bzr, so does not need to be printable.
750
class NoBundleFound(BzrNewError):
751
"""No bundle was found in %(filename)s"""
752
def __init__(self, filename):
753
BzrNewError.__init__(self)
754
self.filename = filename
757
class BundleNotSupported(BzrNewError):
758
"""Unable to handle bundle version %(version)s: %(msg)s"""
759
def __init__(self, version, msg):
760
BzrNewError.__init__(self)
761
self.version = version
765
class MissingText(BzrNewError):
766
"""Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
768
def __init__(self, branch, text_revision, file_id):
769
BzrNewError.__init__(self)
771
self.base = branch.base
772
self.text_revision = text_revision
773
self.file_id = file_id
776
class DuplicateKey(BzrNewError):
777
"""Key %(key)s is already present in map"""
780
class MalformedTransform(BzrNewError):
781
"""Tree transform is malformed %(conflicts)r"""
784
class BzrBadParameter(BzrNewError):
785
"""A bad parameter : %(param)s is not usable.
787
This exception should never be thrown, but it is a base class for all
788
parameter-to-function errors.
790
def __init__(self, param):
791
BzrNewError.__init__(self)
795
class BzrBadParameterNotUnicode(BzrBadParameter):
796
"""Parameter %(param)s is neither unicode nor utf8."""
799
class ReusingTransform(BzrNewError):
800
"""Attempt to reuse a transform that has already been applied."""
803
class CantMoveRoot(BzrNewError):
804
"""Moving the root directory is not supported at this time"""
807
class BzrBadParameterNotString(BzrBadParameter):
808
"""Parameter %(param)s is not a string or unicode string."""
811
class BzrBadParameterMissing(BzrBadParameter):
812
"""Parameter $(param)s is required but not present."""
815
class BzrBadParameterUnicode(BzrBadParameter):
816
"""Parameter %(param)s is unicode but only byte-strings are permitted."""
819
class BzrBadParameterContainsNewline(BzrBadParameter):
820
"""Parameter %(param)s contains a newline."""
823
class DependencyNotPresent(BzrNewError):
824
"""Unable to import library "%(library)s": %(error)s"""
826
def __init__(self, library, error):
827
BzrNewError.__init__(self, library=library, error=error)
830
class ParamikoNotPresent(DependencyNotPresent):
831
"""Unable to import paramiko (required for sftp support): %(error)s"""
833
def __init__(self, error):
834
DependencyNotPresent.__init__(self, 'paramiko', error)
837
class UninitializableFormat(BzrNewError):
838
"""Format %(format)s cannot be initialised by this version of bzr."""
840
def __init__(self, format):
841
BzrNewError.__init__(self)
845
class NoDiff3(BzrNewError):
846
"""Diff3 is not installed on this machine."""
849
class ExistingLimbo(BzrNewError):
850
"""This tree contains left-over files from a failed operation.
851
Please examine %(limbo_dir)s to see if it contains any files you wish to
852
keep, and delete it when you are done.
854
def __init__(self, limbo_dir):
855
BzrNewError.__init__(self)
856
self.limbo_dir = limbo_dir
859
class ImmortalLimbo(BzrNewError):
860
"""Unable to delete transform temporary directory $(limbo_dir)s.
861
Please examine %(limbo_dir)s to see if it contains any files you wish to
862
keep, and delete it when you are done.
864
def __init__(self, limbo_dir):
865
BzrNewError.__init__(self)
866
self.limbo_dir = limbo_dir
869
class OutOfDateTree(BzrNewError):
870
"""Working tree is out of date, please run 'bzr update'."""
872
def __init__(self, tree):
873
BzrNewError.__init__(self)
877
class MergeModifiedFormatError(BzrNewError):
878
"""Error in merge modified format"""
881
class ConflictFormatError(BzrNewError):
882
"""Format error in conflict listings"""
885
class CorruptRepository(BzrNewError):
886
"""An error has been detected in the repository %(repo_path)s.
887
Please run bzr reconcile on this repository."""
889
def __init__(self, repo):
890
BzrNewError.__init__(self)
891
self.repo_path = repo.bzrdir.root_transport.base
894
class UpgradeRequired(BzrNewError):
895
"""To use this feature you must upgrade your branch at %(path)s."""
897
def __init__(self, path):
898
BzrNewError.__init__(self)
902
class LocalRequiresBoundBranch(BzrNewError):
903
"""Cannot perform local-only commits on unbound branches."""
906
class MissingProgressBarFinish(BzrNewError):
907
"""A nested progress bar was not 'finished' correctly."""
910
class UnsupportedOperation(BzrNewError):
911
"""The method %(mname)s is not supported on objects of type %(tname)s."""
912
def __init__(self, method, method_self):
914
self.mname = method.__name__
915
self.tname = type(method_self).__name__
918
class BinaryFile(BzrNewError):
919
"""File is binary but should be text."""
922
class IllegalPath(BzrNewError):
923
"""The path %(path)s is not permitted on this platform"""
925
def __init__(self, path):
926
BzrNewError.__init__(self)
930
class TestamentMismatch(BzrNewError):
931
"""Testament did not match expected value.
932
For revision_id {%(revision_id)s}, expected {%(expected)s}, measured
935
def __init__(self, revision_id, expected, measured):
936
self.revision_id = revision_id
937
self.expected = expected
938
self.measured = measured
941
class BadBundle(Exception): pass
944
class MalformedHeader(BadBundle): pass
947
class MalformedPatches(BadBundle): pass
950
class MalformedFooter(BadBundle): pass
37
def bailout(msg, explanation=[]):
38
ex = BzrError(msg, explanation)
40
trace._tracefile.write('* raising %s\n' % ex)