14
14
# along with this program; if not, write to the Free Software
15
15
# 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.
18
__copyright__ = "Copyright (C) 2005 Canonical Ltd."
19
__author__ = "Martin Pool <mbp@canonical.com>"
21
# TODO: Change to a standard exception pattern:
23
# - docstring of exceptions is a template for formatting the exception
24
# so the __str__ method can be defined only in the superclass
25
# - the arguments to the exception are interpolated into this string
27
# when printing the exception we'd then require special handling only
28
# for built-in exceptions with no decent __str__ method, such as
29
# ValueError and AssertionError. See
30
# scott@canonical.com--2005/hct--devel--0.10 util/errors.py
33
######################################################################
76
35
class BzrError(StandardError):
78
37
# XXX: Should we show the exception class in
92
51
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)
54
class BzrCheckError(BzrError):
58
class InvalidRevisionNumber(BzrError):
104
59
def __str__(self):
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)
60
return 'invalid revision number: %r' % self.args[0]
63
class InvalidRevisionId(BzrError):
158
67
class BzrCommandError(BzrError):
159
68
# 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
167
69
def __str__(self):
168
70
return self.args[0]
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 PathNotChild(BzrNewError):
214
"""Path %(path)r is not a child of path %(base)r%(extra)s"""
215
def __init__(self, path, base, extra=None):
216
BzrNewError.__init__(self)
220
self.extra = ': ' + str(extra)
225
class NotBranchError(PathError):
226
"""Not a branch: %(path)s"""
229
class AlreadyBranchError(PathError):
230
"""Already a branch: %(path)s."""
233
class BranchExistsWithoutWorkingTree(PathError):
234
"""Directory contains a branch, but no working tree \
235
(use bzr checkout if you wish to build a working tree): %(path)s"""
238
class NoRepositoryPresent(BzrNewError):
239
"""No repository present: %(path)r"""
240
def __init__(self, bzrdir):
241
BzrNewError.__init__(self)
242
self.path = bzrdir.transport.clone('..').base
245
class FileInWrongBranch(BzrNewError):
246
"""File %(path)s in not in branch %(branch_base)s."""
248
def __init__(self, branch, path):
249
BzrNewError.__init__(self)
251
self.branch_base = branch.base
73
class NotBranchError(BzrError):
74
"""Specified path is not in a branch"""
76
return 'not a branch: %s' % self.args[0]
255
79
class UnsupportedFormatError(BzrError):
256
"""Specified path is a bzr branch that we recognize but cannot read."""
80
"""Specified path is a bzr branch that we cannot read."""
257
81
def __str__(self):
258
82
return 'unsupported branch format: %s' % self.args[0]
261
class UnknownFormatError(BzrError):
262
"""Specified path is a bzr branch whose format we do not recognize."""
264
return 'unknown branch format: %s' % self.args[0]
267
class IncompatibleFormat(BzrNewError):
268
"""Format %(format)s is not compatible with .bzr version %(bzrdir)s."""
270
def __init__(self, format, bzrdir_format):
271
BzrNewError.__init__(self)
273
self.bzrdir = bzrdir_format
276
class NotVersionedError(BzrNewError):
277
"""%(path)s is not versioned"""
278
def __init__(self, path):
279
BzrNewError.__init__(self)
283
class PathsNotVersionedError(BzrNewError):
284
# used when reporting several paths are not versioned
285
"""Path(s) are not versioned: %(paths_as_string)s"""
287
def __init__(self, paths):
288
from bzrlib.osutils import quotefn
289
BzrNewError.__init__(self)
291
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
294
class PathsDoNotExist(BzrNewError):
295
"""Path(s) do not exist: %(paths_as_string)s"""
297
# used when reporting that paths are neither versioned nor in the working
300
def __init__(self, paths):
302
from bzrlib.osutils import quotefn
303
BzrNewError.__init__(self)
305
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
85
class NotVersionedError(BzrError):
86
"""Specified object is not versioned."""
308
89
class BadFileKindError(BzrError):
309
90
"""Specified file is of a kind that cannot be added.
311
92
(For example a symlink or device file.)"""
314
96
class ForbiddenFileError(BzrError):
315
97
"""Cannot operate on a file because it is a control file."""
318
class LockError(BzrNewError):
319
"""Lock error: %(message)s"""
320
# All exceptions from the lock/unlock functions should be from
321
# this exception class. They will be translated as necessary. The
322
# original exception is available as e.original_error
324
# New code should prefer to raise specific subclasses
325
def __init__(self, message):
326
self.message = message
101
class LockError(Exception):
102
"""All exceptions from the lock/unlock functions should be from
103
this exception class. They will be translated as necessary. The
104
original exception is available as e.original_error
106
def __init__(self, e=None):
107
self.original_error = e
109
Exception.__init__(self, e)
111
Exception.__init__(self)
329
114
class CommitNotPossible(LockError):
330
115
"""A commit was attempted but we do not have a write lock open."""
335
118
class AlreadyCommitted(LockError):
336
119
"""A rollback was requested, but is not able to be accomplished."""
341
122
class ReadOnlyError(LockError):
342
"""A write attempt was made in a read only transaction on %(obj)s"""
343
def __init__(self, obj):
347
class OutSideTransaction(BzrNewError):
348
"""A transaction related operation was attempted after the transaction finished."""
351
class ObjectNotLocked(LockError):
352
"""%(obj)r is not locked"""
353
# this can indicate that any particular object is not locked; see also
354
# LockNotHeld which means that a particular *lock* object is not held by
355
# the caller -- perhaps they should be unified.
356
def __init__(self, obj):
360
class ReadOnlyObjectDirtiedError(ReadOnlyError):
361
"""Cannot change object %(obj)r in read only transaction"""
362
def __init__(self, obj):
366
class UnlockableTransport(LockError):
367
"""Cannot lock: transport is read only: %(transport)s"""
368
def __init__(self, transport):
369
self.transport = transport
372
class LockContention(LockError):
373
"""Could not acquire lock %(lock)s"""
374
# TODO: show full url for lock, combining the transport and relative bits?
375
def __init__(self, lock):
379
class LockBroken(LockError):
380
"""Lock was broken while still open: %(lock)s - check storage consistency!"""
381
def __init__(self, lock):
385
class LockBreakMismatch(LockError):
386
"""Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"""
387
def __init__(self, lock, holder, target):
393
class LockNotHeld(LockError):
394
"""Lock not held: %(lock)s"""
395
def __init__(self, lock):
399
class PointlessCommit(BzrNewError):
400
"""No changes to commit"""
403
class UpgradeReadonly(BzrNewError):
404
"""Upgrade URL cannot work with readonly URL's."""
407
class UpToDateFormat(BzrNewError):
408
"""The branch format %(format)s is already at the most recent format."""
410
def __init__(self, format):
411
BzrNewError.__init__(self)
416
class StrictCommitFailed(Exception):
417
"""Commit refused because there are unknowns in the tree."""
123
"""A write attempt was made in a read only transaction."""
126
class PointlessCommit(Exception):
127
"""Commit failed because nothing was changed."""
420
130
class NoSuchRevision(BzrError):
482
196
class AmbiguousBase(BzrError):
483
197
def __init__(self, bases):
484
warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
486
198
msg = "The correct base is unclear, becase %s are all equally close" %\
488
200
BzrError.__init__(self, msg)
489
201
self.bases = bases
492
203
class NoCommits(BzrError):
493
204
def __init__(self, branch):
494
205
msg = "Branch %s has no commits." % branch
495
206
BzrError.__init__(self, msg)
498
208
class UnlistableStore(BzrError):
499
209
def __init__(self, store):
500
210
BzrError.__init__(self, "Store %s is not listable" % store)
504
212
class UnlistableBranch(BzrError):
505
213
def __init__(self, br):
506
214
BzrError.__init__(self, "Stores for branch %s are not listable" % br)
509
class BoundBranchOutOfDate(BzrNewError):
510
"""Bound branch %(branch)s is out of date with master branch %(master)s."""
511
def __init__(self, branch, master):
512
BzrNewError.__init__(self)
517
class CommitToDoubleBoundBranch(BzrNewError):
518
"""Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
519
def __init__(self, branch, master, remote):
520
BzrNewError.__init__(self)
526
class OverwriteBoundBranch(BzrNewError):
527
"""Cannot pull --overwrite to a branch which is bound %(branch)s"""
528
def __init__(self, branch):
529
BzrNewError.__init__(self)
533
class BoundBranchConnectionFailure(BzrNewError):
534
"""Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
535
def __init__(self, branch, target, error):
536
BzrNewError.__init__(self)
542
class WeaveError(BzrNewError):
543
"""Error in processing weave: %(message)s"""
545
def __init__(self, message=None):
546
BzrNewError.__init__(self)
547
self.message = message
550
class WeaveRevisionAlreadyPresent(WeaveError):
551
"""Revision {%(revision_id)s} already present in %(weave)s"""
552
def __init__(self, revision_id, weave):
554
WeaveError.__init__(self)
555
self.revision_id = revision_id
559
class WeaveRevisionNotPresent(WeaveError):
560
"""Revision {%(revision_id)s} not present in %(weave)s"""
562
def __init__(self, revision_id, weave):
563
WeaveError.__init__(self)
564
self.revision_id = revision_id
568
class WeaveFormatError(WeaveError):
569
"""Weave invariant violated: %(what)s"""
571
def __init__(self, what):
572
WeaveError.__init__(self)
576
class WeaveParentMismatch(WeaveError):
577
"""Parents are mismatched between two revisions."""
580
class WeaveInvalidChecksum(WeaveError):
581
"""Text did not match it's checksum: %(message)s"""
584
class WeaveTextDiffers(WeaveError):
585
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
587
def __init__(self, revision_id, weave_a, weave_b):
588
WeaveError.__init__(self)
589
self.revision_id = revision_id
590
self.weave_a = weave_a
591
self.weave_b = weave_b
594
class WeaveTextDiffers(WeaveError):
595
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
597
def __init__(self, revision_id, weave_a, weave_b):
598
WeaveError.__init__(self)
599
self.revision_id = revision_id
600
self.weave_a = weave_a
601
self.weave_b = weave_b
604
class VersionedFileError(BzrNewError):
605
"""Versioned file error."""
608
class RevisionNotPresent(VersionedFileError):
609
"""Revision {%(revision_id)s} not present in %(file_id)s."""
611
def __init__(self, revision_id, file_id):
612
VersionedFileError.__init__(self)
613
self.revision_id = revision_id
614
self.file_id = file_id
617
class RevisionAlreadyPresent(VersionedFileError):
618
"""Revision {%(revision_id)s} already present in %(file_id)s."""
620
def __init__(self, revision_id, file_id):
621
VersionedFileError.__init__(self)
622
self.revision_id = revision_id
623
self.file_id = file_id
626
class KnitError(BzrNewError):
630
class KnitHeaderError(KnitError):
631
"""Knit header error: %(badline)r unexpected"""
633
def __init__(self, badline):
634
KnitError.__init__(self)
635
self.badline = badline
638
class KnitCorrupt(KnitError):
639
"""Knit %(filename)s corrupt: %(how)s"""
641
def __init__(self, filename, how):
642
KnitError.__init__(self)
643
self.filename = filename
647
class NoSuchExportFormat(BzrNewError):
648
"""Export format %(format)r not supported"""
649
def __init__(self, format):
650
BzrNewError.__init__(self)
217
from bzrlib.weave import WeaveError, WeaveParentMismatch
654
219
class TransportError(BzrError):
655
220
"""All errors thrown by Transport implementations should derive
674
class ConnectionError(TransportError):
675
"""A connection problem prevents file retrieval.
676
This does not indicate whether the file exists or not; it indicates that a
677
precondition for requesting the file was not met.
679
def __init__(self, msg=None, orig_error=None):
680
TransportError.__init__(self, msg=msg, orig_error=orig_error)
237
class NonRelativePath(TransportError):
238
"""An absolute path was supplied, that could not be decoded into
243
class NoSuchFile(TransportError, IOError):
244
"""A get() was issued for a file that doesn't exist."""
246
# XXX: Is multiple inheritance for exceptions really needed?
249
return 'no such file: ' + self.msg
251
def __init__(self, msg=None, orig_error=None):
253
TransportError.__init__(self, msg=msg, orig_error=orig_error)
254
IOError.__init__(self, errno.ENOENT, self.msg)
256
class FileExists(TransportError, OSError):
257
"""An operation was attempted, which would overwrite an entry,
258
but overwritting is not supported.
260
mkdir() can throw this, but put() just overwites existing files.
262
# XXX: Is multiple inheritance for exceptions really needed?
263
def __init__(self, msg=None, orig_error=None):
265
TransportError.__init__(self, msg=msg, orig_error=orig_error)
266
OSError.__init__(self, errno.EEXIST, self.msg)
268
class PermissionDenied(TransportError):
269
"""An operation cannot succeed because of a lack of permissions."""
683
272
class ConnectionReset(TransportError):
684
273
"""The connection has been closed."""
688
276
class ConflictsInTree(BzrError):
689
277
def __init__(self):
690
278
BzrError.__init__(self, "Working tree has conflicts.")
693
class ParseConfigError(BzrError):
694
def __init__(self, errors, filename):
697
message = "Error(s) parsing config file %s:\n%s" % \
698
(filename, ('\n'.join(e.message for e in errors)))
699
BzrError.__init__(self, message)
702
280
class SigningFailed(BzrError):
703
281
def __init__(self, command_line):
704
282
BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
708
class WorkingTreeNotRevision(BzrError):
709
def __init__(self, tree):
710
BzrError.__init__(self, "The working tree for %s has changed since"
711
" last commit, but weave merge requires that it be"
712
" unchanged." % tree.basedir)
715
class CantReprocessAndShowBase(BzrNewError):
716
"""Can't reprocess and show base.
717
Reprocessing obscures relationship of conflicting lines to base."""
720
class GraphCycleError(BzrNewError):
721
"""Cycle in graph %(graph)r"""
722
def __init__(self, graph):
723
BzrNewError.__init__(self)
727
class NotConflicted(BzrNewError):
728
"""File %(filename)s is not conflicted."""
730
def __init__(self, filename):
731
BzrNewError.__init__(self)
732
self.filename = filename
735
class MustUseDecorated(Exception):
736
"""A decorating function has requested its original command be used.
738
This should never escape bzr, so does not need to be printable.
742
class MissingText(BzrNewError):
743
"""Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
745
def __init__(self, branch, text_revision, file_id):
746
BzrNewError.__init__(self)
748
self.base = branch.base
749
self.text_revision = text_revision
750
self.file_id = file_id
753
class DuplicateKey(BzrNewError):
754
"""Key %(key)s is already present in map"""
757
class MalformedTransform(BzrNewError):
758
"""Tree transform is malformed %(conflicts)r"""
761
class BzrBadParameter(BzrNewError):
762
"""A bad parameter : %(param)s is not usable.
764
This exception should never be thrown, but it is a base class for all
765
parameter-to-function errors.
767
def __init__(self, param):
768
BzrNewError.__init__(self)
772
class BzrBadParameterNotUnicode(BzrBadParameter):
773
"""Parameter %(param)s is neither unicode nor utf8."""
776
class ReusingTransform(BzrNewError):
777
"""Attempt to reuse a transform that has already been applied."""
780
class CantMoveRoot(BzrNewError):
781
"""Moving the root directory is not supported at this time"""
784
class BzrBadParameterNotString(BzrBadParameter):
785
"""Parameter %(param)s is not a string or unicode string."""
788
class BzrBadParameterMissing(BzrBadParameter):
789
"""Parameter $(param)s is required but not present."""
792
class BzrBadParameterUnicode(BzrBadParameter):
793
"""Parameter %(param)s is unicode but only byte-strings are permitted."""
796
class BzrBadParameterContainsNewline(BzrBadParameter):
797
"""Parameter %(param)s contains a newline."""
800
class DependencyNotPresent(BzrNewError):
801
"""Unable to import library "%(library)s": %(error)s"""
803
def __init__(self, library, error):
804
BzrNewError.__init__(self, library=library, error=error)
807
class ParamikoNotPresent(DependencyNotPresent):
808
"""Unable to import paramiko (required for sftp support): %(error)s"""
810
def __init__(self, error):
811
DependencyNotPresent.__init__(self, 'paramiko', error)
814
class UninitializableFormat(BzrNewError):
815
"""Format %(format)s cannot be initialised by this version of bzr."""
817
def __init__(self, format):
818
BzrNewError.__init__(self)
822
class NoDiff3(BzrNewError):
823
"""Diff3 is not installed on this machine."""
826
class ExistingLimbo(BzrNewError):
827
"""This tree contains left-over files from a failed operation.
828
Please examine %(limbo_dir)s to see if it contains any files you wish to
829
keep, and delete it when you are done.
831
def __init__(self, limbo_dir):
832
BzrNewError.__init__(self)
833
self.limbo_dir = limbo_dir
836
class ImmortalLimbo(BzrNewError):
837
"""Unable to delete transform temporary directory $(limbo_dir)s.
838
Please examine %(limbo_dir)s to see if it contains any files you wish to
839
keep, and delete it when you are done.
841
def __init__(self, limbo_dir):
842
BzrNewError.__init__(self)
843
self.limbo_dir = limbo_dir
846
class OutOfDateTree(BzrNewError):
847
"""Working tree is out of date, please run 'bzr update'."""
849
def __init__(self, tree):
850
BzrNewError.__init__(self)
854
class MergeModifiedFormatError(BzrNewError):
855
"""Error in merge modified format"""
858
class ConflictFormatError(BzrNewError):
859
"""Format error in conflict listings"""
862
class CorruptRepository(BzrNewError):
863
"""An error has been detected in the repository %(repo_path)s.
864
Please run bzr reconcile on this repository."""
866
def __init__(self, repo):
867
BzrNewError.__init__(self)
868
self.repo_path = repo.bzrdir.root_transport.base
871
class UpgradeRequired(BzrNewError):
872
"""To use this feature you must upgrade your branch at %(path)s."""
874
def __init__(self, path):
875
BzrNewError.__init__(self)
879
class LocalRequiresBoundBranch(BzrNewError):
880
"""Cannot perform local-only commits on unbound branches."""
883
class MissingProgressBarFinish(BzrNewError):
884
"""A nested progress bar was not 'finished' correctly."""
887
class UnsupportedOperation(BzrNewError):
888
"""The method %(mname)s is not supported on objects of type %(tname)s."""
889
def __init__(self, method, method_self):
891
self.mname = method.__name__
892
self.tname = type(method_self).__name__
895
class BinaryFile(BzrNewError):
896
"""File is binary but should be text."""
899
class IllegalPath(BzrNewError):
900
"""The path %(path)s is not permitted on this platform"""
902
def __init__(self, path):
903
BzrNewError.__init__(self)