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')
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.
19
__copyright__ = "Copyright (C) 2005 Canonical Ltd."
20
__author__ = "Martin Pool <mbp@canonical.com>"
23
######################################################################
76
25
class BzrError(StandardError):
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
BzrNewError.__init__(self)
138
self.revision_id = revision_id
142
class NoWorkingTree(BzrNewError):
143
"""No WorkingTree exists for %(base)s."""
145
def __init__(self, base):
146
BzrNewError.__init__(self)
150
class NotLocalUrl(BzrNewError):
151
"""%(url)s is not a local path."""
153
def __init__(self, url):
154
BzrNewError.__init__(self)
158
class BzrCommandError(BzrError):
159
# Error from malformed user command
160
# This is being misused as a generic exception
161
# pleae subclass. RBC 20051030
163
# I think it's a waste of effort to differentiate between errors that
164
# are not intended to be caught anyway. UI code need not subclass
165
# BzrCommandError, and non-UI code should not throw a subclass of
166
# BzrCommandError. ADHB 20051211
171
class BzrOptionError(BzrCommandError):
172
"""Some missing or otherwise incorrect option was supplied."""
175
class StrictCommitFailed(Exception):
176
"""Commit refused because there are unknowns in the tree."""
179
# XXX: Should be unified with TransportError; they seem to represent the
181
class PathError(BzrNewError):
182
"""Generic path error: %(path)r%(extra)s)"""
184
def __init__(self, path, extra=None):
185
BzrNewError.__init__(self)
188
self.extra = ': ' + str(extra)
193
class NoSuchFile(PathError):
194
"""No such file: %(path)r%(extra)s"""
197
class FileExists(PathError):
198
"""File exists: %(path)r%(extra)s"""
201
class DirectoryNotEmpty(PathError):
202
"""Directory not empty: %(path)r%(extra)s"""
205
class ResourceBusy(PathError):
206
"""Device or resource busy: %(path)r%(extra)s"""
209
class PermissionDenied(PathError):
210
"""Permission denied: %(path)r%(extra)s"""
213
class InvalidURL(PathError):
214
"""Invalid url supplied to transport: %(path)r%(extra)s"""
217
class InvalidURLJoin(PathError):
218
"""Invalid URL join request: %(args)s%(extra)s"""
220
def __init__(self, msg, base, args):
221
PathError.__init__(self, base, msg)
223
self.args.extend(args)
226
class PathNotChild(BzrNewError):
227
"""Path %(path)r is not a child of path %(base)r%(extra)s"""
228
def __init__(self, path, base, extra=None):
229
BzrNewError.__init__(self)
233
self.extra = ': ' + str(extra)
238
# TODO: This is given a URL; we try to unescape it but doing that from inside
239
# the exception object is a bit undesirable.
240
# TODO: Probably this behavior of should be a common superclass
241
class NotBranchError(PathError):
242
"Not a branch: %(path)s"
244
def __init__(self, path):
245
import bzrlib.urlutils as urlutils
246
self.path = urlutils.unescape_for_display(path, 'ascii')
249
class AlreadyBranchError(PathError):
250
"""Already a branch: %(path)s."""
253
class BranchExistsWithoutWorkingTree(PathError):
254
"""Directory contains a branch, but no working tree \
255
(use bzr checkout if you wish to build a working tree): %(path)s"""
258
class NoRepositoryPresent(BzrNewError):
259
"""No repository present: %(path)r"""
260
def __init__(self, bzrdir):
261
BzrNewError.__init__(self)
262
self.path = bzrdir.transport.clone('..').base
265
class FileInWrongBranch(BzrNewError):
266
"""File %(path)s in not in branch %(branch_base)s."""
268
def __init__(self, branch, path):
269
BzrNewError.__init__(self)
271
self.branch_base = branch.base
275
class UnsupportedFormatError(BzrError):
276
"""Specified path is a bzr branch that we recognize but cannot read."""
278
return 'unsupported branch format: %s' % self.args[0]
281
class UnknownFormatError(BzrError):
282
"""Specified path is a bzr branch whose format we do not recognize."""
284
return 'unknown branch format: %s' % self.args[0]
287
class IncompatibleFormat(BzrNewError):
288
"""Format %(format)s is not compatible with .bzr version %(bzrdir)s."""
290
def __init__(self, format, bzrdir_format):
291
BzrNewError.__init__(self)
293
self.bzrdir = bzrdir_format
296
class NotVersionedError(BzrNewError):
297
"""%(path)s is not versioned"""
298
def __init__(self, path):
299
BzrNewError.__init__(self)
303
class PathsNotVersionedError(BzrNewError):
304
# used when reporting several paths are not versioned
305
"""Path(s) are not versioned: %(paths_as_string)s"""
307
def __init__(self, paths):
308
from bzrlib.osutils import quotefn
309
BzrNewError.__init__(self)
311
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
314
class PathsDoNotExist(BzrNewError):
315
"""Path(s) do not exist: %(paths_as_string)s"""
317
# used when reporting that paths are neither versioned nor in the working
320
def __init__(self, paths):
322
from bzrlib.osutils import quotefn
323
BzrNewError.__init__(self)
325
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
328
class BadFileKindError(BzrError):
329
"""Specified file is of a kind that cannot be added.
331
(For example a symlink or device file.)"""
334
class ForbiddenFileError(BzrError):
335
"""Cannot operate on a file because it is a control file."""
338
class LockError(BzrNewError):
339
"""Lock error: %(message)s"""
340
# All exceptions from the lock/unlock functions should be from
341
# this exception class. They will be translated as necessary. The
342
# original exception is available as e.original_error
344
# New code should prefer to raise specific subclasses
345
def __init__(self, message):
346
self.message = message
349
class CommitNotPossible(LockError):
350
"""A commit was attempted but we do not have a write lock open."""
355
class AlreadyCommitted(LockError):
356
"""A rollback was requested, but is not able to be accomplished."""
361
class ReadOnlyError(LockError):
362
"""A write attempt was made in a read only transaction on %(obj)s"""
363
def __init__(self, obj):
367
class OutSideTransaction(BzrNewError):
368
"""A transaction related operation was attempted after the transaction finished."""
371
class ObjectNotLocked(LockError):
372
"""%(obj)r is not locked"""
373
# this can indicate that any particular object is not locked; see also
374
# LockNotHeld which means that a particular *lock* object is not held by
375
# the caller -- perhaps they should be unified.
376
def __init__(self, obj):
380
class ReadOnlyObjectDirtiedError(ReadOnlyError):
381
"""Cannot change object %(obj)r in read only transaction"""
382
def __init__(self, obj):
386
class UnlockableTransport(LockError):
387
"""Cannot lock: transport is read only: %(transport)s"""
388
def __init__(self, transport):
389
self.transport = transport
392
class LockContention(LockError):
393
"""Could not acquire lock %(lock)s"""
394
# TODO: show full url for lock, combining the transport and relative bits?
395
def __init__(self, lock):
399
class LockBroken(LockError):
400
"""Lock was broken while still open: %(lock)s - check storage consistency!"""
401
def __init__(self, lock):
405
class LockBreakMismatch(LockError):
406
"""Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"""
407
def __init__(self, lock, holder, target):
413
class LockNotHeld(LockError):
414
"""Lock not held: %(lock)s"""
415
def __init__(self, lock):
419
class PointlessCommit(BzrNewError):
420
"""No changes to commit"""
423
class UpgradeReadonly(BzrNewError):
424
"""Upgrade URL cannot work with readonly URL's."""
427
class UpToDateFormat(BzrNewError):
428
"""The branch format %(format)s is already at the most recent format."""
430
def __init__(self, format):
431
BzrNewError.__init__(self)
436
class StrictCommitFailed(Exception):
437
"""Commit refused because there are unknowns in the tree."""
440
class NoSuchRevision(BzrError):
441
def __init__(self, branch, revision):
443
self.revision = revision
444
msg = "Branch %s has no revision %s" % (branch, revision)
445
BzrError.__init__(self, msg)
448
class HistoryMissing(BzrError):
449
def __init__(self, branch, object_type, object_id):
451
BzrError.__init__(self,
452
'%s is missing %s {%s}'
453
% (branch, object_type, object_id))
456
class DivergedBranches(BzrError):
458
def __init__(self, branch1, branch2):
459
BzrError.__init__(self, "These branches have diverged. Try merge.")
460
self.branch1 = branch1
461
self.branch2 = branch2
464
class UnrelatedBranches(BzrCommandError):
466
msg = "Branches have no common ancestor, and no base revision"\
468
BzrCommandError.__init__(self, msg)
471
class NoCommonAncestor(BzrError):
472
def __init__(self, revision_a, revision_b):
473
msg = "Revisions have no common ancestor: %s %s." \
474
% (revision_a, revision_b)
475
BzrError.__init__(self, msg)
478
class NoCommonRoot(BzrError):
479
def __init__(self, revision_a, revision_b):
480
msg = "Revisions are not derived from the same root: %s %s." \
481
% (revision_a, revision_b)
482
BzrError.__init__(self, msg)
486
class NotAncestor(BzrError):
487
def __init__(self, rev_id, not_ancestor_id):
488
msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id,
490
BzrError.__init__(self, msg)
492
self.not_ancestor_id = not_ancestor_id
495
class InstallFailed(BzrError):
496
def __init__(self, revisions):
497
msg = "Could not install revisions:\n%s" % " ,".join(revisions)
498
BzrError.__init__(self, msg)
499
self.revisions = revisions
502
class AmbiguousBase(BzrError):
503
def __init__(self, bases):
504
warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
506
msg = "The correct base is unclear, becase %s are all equally close" %\
508
BzrError.__init__(self, msg)
512
class NoCommits(BzrError):
513
def __init__(self, branch):
514
msg = "Branch %s has no commits." % branch
515
BzrError.__init__(self, msg)
518
class UnlistableStore(BzrError):
519
def __init__(self, store):
520
BzrError.__init__(self, "Store %s is not listable" % store)
524
class UnlistableBranch(BzrError):
525
def __init__(self, br):
526
BzrError.__init__(self, "Stores for branch %s are not listable" % br)
529
class BoundBranchOutOfDate(BzrNewError):
530
"""Bound branch %(branch)s is out of date with master branch %(master)s."""
531
def __init__(self, branch, master):
532
BzrNewError.__init__(self)
537
class CommitToDoubleBoundBranch(BzrNewError):
538
"""Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
539
def __init__(self, branch, master, remote):
540
BzrNewError.__init__(self)
546
class OverwriteBoundBranch(BzrNewError):
547
"""Cannot pull --overwrite to a branch which is bound %(branch)s"""
548
def __init__(self, branch):
549
BzrNewError.__init__(self)
553
class BoundBranchConnectionFailure(BzrNewError):
554
"""Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
555
def __init__(self, branch, target, error):
556
BzrNewError.__init__(self)
562
class WeaveError(BzrNewError):
563
"""Error in processing weave: %(message)s"""
565
def __init__(self, message=None):
566
BzrNewError.__init__(self)
567
self.message = message
570
class WeaveRevisionAlreadyPresent(WeaveError):
571
"""Revision {%(revision_id)s} already present in %(weave)s"""
572
def __init__(self, revision_id, weave):
574
WeaveError.__init__(self)
575
self.revision_id = revision_id
579
class WeaveRevisionNotPresent(WeaveError):
580
"""Revision {%(revision_id)s} not present in %(weave)s"""
582
def __init__(self, revision_id, weave):
583
WeaveError.__init__(self)
584
self.revision_id = revision_id
588
class WeaveFormatError(WeaveError):
589
"""Weave invariant violated: %(what)s"""
591
def __init__(self, what):
592
WeaveError.__init__(self)
596
class WeaveParentMismatch(WeaveError):
597
"""Parents are mismatched between two revisions."""
600
class WeaveInvalidChecksum(WeaveError):
601
"""Text did not match it's checksum: %(message)s"""
604
class WeaveTextDiffers(WeaveError):
605
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
607
def __init__(self, revision_id, weave_a, weave_b):
608
WeaveError.__init__(self)
609
self.revision_id = revision_id
610
self.weave_a = weave_a
611
self.weave_b = weave_b
614
class WeaveTextDiffers(WeaveError):
615
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
617
def __init__(self, revision_id, weave_a, weave_b):
618
WeaveError.__init__(self)
619
self.revision_id = revision_id
620
self.weave_a = weave_a
621
self.weave_b = weave_b
624
class VersionedFileError(BzrNewError):
625
"""Versioned file error."""
628
class RevisionNotPresent(VersionedFileError):
629
"""Revision {%(revision_id)s} not present in %(file_id)s."""
631
def __init__(self, revision_id, file_id):
632
VersionedFileError.__init__(self)
633
self.revision_id = revision_id
634
self.file_id = file_id
637
class RevisionAlreadyPresent(VersionedFileError):
638
"""Revision {%(revision_id)s} already present in %(file_id)s."""
640
def __init__(self, revision_id, file_id):
641
VersionedFileError.__init__(self)
642
self.revision_id = revision_id
643
self.file_id = file_id
646
class KnitError(BzrNewError):
650
class KnitHeaderError(KnitError):
651
"""Knit header error: %(badline)r unexpected"""
653
def __init__(self, badline):
654
KnitError.__init__(self)
655
self.badline = badline
658
class KnitCorrupt(KnitError):
659
"""Knit %(filename)s corrupt: %(how)s"""
661
def __init__(self, filename, how):
662
KnitError.__init__(self)
663
self.filename = filename
667
class NoSuchExportFormat(BzrNewError):
668
"""Export format %(format)r not supported"""
669
def __init__(self, format):
670
BzrNewError.__init__(self)
674
class TransportError(BzrError):
675
"""All errors thrown by Transport implementations should derive
678
def __init__(self, msg=None, orig_error=None):
679
if msg is None and orig_error is not None:
680
msg = str(orig_error)
681
BzrError.__init__(self, msg)
683
self.orig_error = orig_error
686
# A set of semi-meaningful errors which can be thrown
687
class TransportNotPossible(TransportError):
688
"""This is for transports where a specific function is explicitly not
689
possible. Such as pushing files to an HTTP server.
694
class ConnectionError(TransportError):
695
"""A connection problem prevents file retrieval.
696
This does not indicate whether the file exists or not; it indicates that a
697
precondition for requesting the file was not met.
699
def __init__(self, msg=None, orig_error=None):
700
TransportError.__init__(self, msg=msg, orig_error=orig_error)
703
class ConnectionReset(TransportError):
704
"""The connection has been closed."""
708
class ConflictsInTree(BzrError):
710
BzrError.__init__(self, "Working tree has conflicts.")
713
class ParseConfigError(BzrError):
714
def __init__(self, errors, filename):
717
message = "Error(s) parsing config file %s:\n%s" % \
718
(filename, ('\n'.join(e.message for e in errors)))
719
BzrError.__init__(self, message)
722
class SigningFailed(BzrError):
723
def __init__(self, command_line):
724
BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
728
class WorkingTreeNotRevision(BzrError):
729
def __init__(self, tree):
730
BzrError.__init__(self, "The working tree for %s has changed since"
731
" last commit, but weave merge requires that it be"
732
" unchanged." % tree.basedir)
735
class CantReprocessAndShowBase(BzrNewError):
736
"""Can't reprocess and show base.
737
Reprocessing obscures relationship of conflicting lines to base."""
740
class GraphCycleError(BzrNewError):
741
"""Cycle in graph %(graph)r"""
742
def __init__(self, graph):
743
BzrNewError.__init__(self)
747
class NotConflicted(BzrNewError):
748
"""File %(filename)s is not conflicted."""
750
def __init__(self, filename):
751
BzrNewError.__init__(self)
752
self.filename = filename
755
class MustUseDecorated(Exception):
756
"""A decorating function has requested its original command be used.
758
This should never escape bzr, so does not need to be printable.
762
class MissingText(BzrNewError):
763
"""Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
765
def __init__(self, branch, text_revision, file_id):
766
BzrNewError.__init__(self)
768
self.base = branch.base
769
self.text_revision = text_revision
770
self.file_id = file_id
773
class DuplicateKey(BzrNewError):
774
"""Key %(key)s is already present in map"""
777
class MalformedTransform(BzrNewError):
778
"""Tree transform is malformed %(conflicts)r"""
781
class BzrBadParameter(BzrNewError):
782
"""A bad parameter : %(param)s is not usable.
784
This exception should never be thrown, but it is a base class for all
785
parameter-to-function errors.
787
def __init__(self, param):
788
BzrNewError.__init__(self)
792
class BzrBadParameterNotUnicode(BzrBadParameter):
793
"""Parameter %(param)s is neither unicode nor utf8."""
796
class ReusingTransform(BzrNewError):
797
"""Attempt to reuse a transform that has already been applied."""
800
class CantMoveRoot(BzrNewError):
801
"""Moving the root directory is not supported at this time"""
804
class BzrBadParameterNotString(BzrBadParameter):
805
"""Parameter %(param)s is not a string or unicode string."""
808
class BzrBadParameterMissing(BzrBadParameter):
809
"""Parameter $(param)s is required but not present."""
812
class BzrBadParameterUnicode(BzrBadParameter):
813
"""Parameter %(param)s is unicode but only byte-strings are permitted."""
816
class BzrBadParameterContainsNewline(BzrBadParameter):
817
"""Parameter %(param)s contains a newline."""
820
class DependencyNotPresent(BzrNewError):
821
"""Unable to import library "%(library)s": %(error)s"""
823
def __init__(self, library, error):
824
BzrNewError.__init__(self, library=library, error=error)
827
class ParamikoNotPresent(DependencyNotPresent):
828
"""Unable to import paramiko (required for sftp support): %(error)s"""
830
def __init__(self, error):
831
DependencyNotPresent.__init__(self, 'paramiko', error)
834
class UninitializableFormat(BzrNewError):
835
"""Format %(format)s cannot be initialised by this version of bzr."""
837
def __init__(self, format):
838
BzrNewError.__init__(self)
842
class NoDiff3(BzrNewError):
843
"""Diff3 is not installed on this machine."""
846
class ExistingLimbo(BzrNewError):
847
"""This tree contains left-over files from a failed operation.
848
Please examine %(limbo_dir)s to see if it contains any files you wish to
849
keep, and delete it when you are done.
851
def __init__(self, limbo_dir):
852
BzrNewError.__init__(self)
853
self.limbo_dir = limbo_dir
856
class ImmortalLimbo(BzrNewError):
857
"""Unable to delete transform temporary directory $(limbo_dir)s.
858
Please examine %(limbo_dir)s to see if it contains any files you wish to
859
keep, and delete it when you are done.
861
def __init__(self, limbo_dir):
862
BzrNewError.__init__(self)
863
self.limbo_dir = limbo_dir
866
class OutOfDateTree(BzrNewError):
867
"""Working tree is out of date, please run 'bzr update'."""
869
def __init__(self, tree):
870
BzrNewError.__init__(self)
874
class MergeModifiedFormatError(BzrNewError):
875
"""Error in merge modified format"""
878
class ConflictFormatError(BzrNewError):
879
"""Format error in conflict listings"""
882
class CorruptRepository(BzrNewError):
883
"""An error has been detected in the repository %(repo_path)s.
884
Please run bzr reconcile on this repository."""
886
def __init__(self, repo):
887
BzrNewError.__init__(self)
888
self.repo_path = repo.bzrdir.root_transport.base
891
class UpgradeRequired(BzrNewError):
892
"""To use this feature you must upgrade your branch at %(path)s."""
894
def __init__(self, path):
895
BzrNewError.__init__(self)
899
class LocalRequiresBoundBranch(BzrNewError):
900
"""Cannot perform local-only commits on unbound branches."""
903
class MissingProgressBarFinish(BzrNewError):
904
"""A nested progress bar was not 'finished' correctly."""
907
class UnsupportedOperation(BzrNewError):
908
"""The method %(mname)s is not supported on objects of type %(tname)s."""
909
def __init__(self, method, method_self):
911
self.mname = method.__name__
912
self.tname = type(method_self).__name__
915
class BinaryFile(BzrNewError):
916
"""File is binary but should be text."""
919
class IllegalPath(BzrNewError):
920
"""The path %(path)s is not permitted on this platform"""
922
def __init__(self, path):
923
BzrNewError.__init__(self)
28
class BzrCheckError(BzrError):
34
def bailout(msg, explanation=[]):
35
ex = BzrError(msg, explanation)
37
trace._tracefile.write('* raising %s\n' % ex)