1
# Copyright (C) 2005, 2006 Canonical
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
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
72
class BzrError(StandardError):
74
# XXX: Should we show the exception class in
75
# exceptions that don't provide their own message?
76
# maybe it should be done at a higher level
77
## n = self.__class__.__name__ + ': '
79
if len(self.args) == 1:
80
return str(self.args[0])
81
elif len(self.args) == 2:
82
# further explanation or suggestions
84
return n + '\n '.join([self.args[0]] + self.args[1])
86
return n + "%r" % self
88
return n + `self.args`
91
class BzrNewError(BzrError):
93
# base classes should override the docstring with their human-
94
# readable explanation
96
def __init__(self, **kwds):
97
for key, value in kwds.items():
98
setattr(self, key, value)
102
return self.__doc__ % self.__dict__
103
except (NameError, ValueError, KeyError), e:
104
return 'Unprintable exception %s: %s' \
105
% (self.__class__.__name__, str(e))
108
class BzrCheckError(BzrNewError):
109
"""Internal check failed: %(message)s"""
111
def __init__(self, message):
112
BzrNewError.__init__(self)
113
self.message = message
116
class InvalidEntryName(BzrNewError):
117
"""Invalid entry name: %(name)s"""
118
def __init__(self, name):
119
BzrNewError.__init__(self)
123
class InvalidRevisionNumber(BzrNewError):
124
"""Invalid revision number %(revno)d"""
125
def __init__(self, revno):
126
BzrNewError.__init__(self)
130
class InvalidRevisionId(BzrNewError):
131
"""Invalid revision-id {%(revision_id)s} in %(branch)s"""
132
def __init__(self, revision_id, branch):
133
BzrNewError.__init__(self)
134
self.revision_id = revision_id
138
class NoWorkingTree(BzrNewError):
139
"""No WorkingTree exists for %s(base)."""
141
def __init__(self, base):
142
BzrNewError.__init__(self)
146
class NotLocalUrl(BzrNewError):
147
"""%s(url) is not a local path."""
149
def __init__(self, url):
150
BzrNewError.__init__(self)
154
class BzrCommandError(BzrError):
155
# Error from malformed user command
156
# This is being misused as a generic exception
157
# pleae subclass. RBC 20051030
159
# I think it's a waste of effort to differentiate between errors that
160
# are not intended to be caught anyway. UI code need not subclass
161
# BzrCommandError, and non-UI code should not throw a subclass of
162
# BzrCommandError. ADHB 20051211
167
class BzrOptionError(BzrCommandError):
168
"""Some missing or otherwise incorrect option was supplied."""
171
class StrictCommitFailed(Exception):
172
"""Commit refused because there are unknowns in the tree."""
175
class PathError(BzrNewError):
176
"""Generic path error: %(path)r%(extra)s)"""
178
def __init__(self, path, extra=None):
179
BzrNewError.__init__(self)
182
self.extra = ': ' + str(extra)
187
class NoSuchFile(PathError):
188
"""No such file: %(path)r%(extra)s"""
191
class FileExists(PathError):
192
"""File exists: %(path)r%(extra)s"""
195
class DirectoryNotEmpty(PathError):
196
"""Directory not empty: %(path)r%(extra)s"""
199
class ResourceBusy(PathError):
200
"""Device or resource busy: %(path)r%(extra)s"""
203
class PermissionDenied(PathError):
204
"""Permission denied: %(path)r%(extra)s"""
207
class PathNotChild(BzrNewError):
208
"""Path %(path)r is not a child of path %(base)r%(extra)s"""
209
def __init__(self, path, base, extra=None):
210
BzrNewError.__init__(self)
214
self.extra = ': ' + str(extra)
219
class NotBranchError(PathError):
220
"""Not a branch: %(path)s"""
223
class AlreadyBranchError(PathError):
224
"""Already a branch: %(path)s. Use `bzr checkout` to build a working tree."""
227
class NoRepositoryPresent(BzrNewError):
228
"""Not repository present: %(path)r"""
229
def __init__(self, bzrdir):
230
BzrNewError.__init__(self)
231
self.path = bzrdir.transport.clone('..').base
234
class FileInWrongBranch(BzrNewError):
235
"""File %(path)s in not in branch %(branch_base)s."""
237
def __init__(self, branch, path):
238
BzrNewError.__init__(self)
240
self.branch_base = branch.base
244
class UnsupportedFormatError(BzrError):
245
"""Specified path is a bzr branch that we recognize but cannot read."""
247
return 'unsupported branch format: %s' % self.args[0]
250
class UnknownFormatError(BzrError):
251
"""Specified path is a bzr branch whose format we do not recognize."""
253
return 'unknown branch format: %s' % self.args[0]
256
class IncompatibleFormat(BzrNewError):
257
"""Format %(format)s is not compatible with .bzr version %(bzrdir)s."""
259
def __init__(self, format, bzrdir_format):
260
BzrNewError.__init__(self)
262
self.bzrdir = bzrdir_format
265
class NotVersionedError(BzrNewError):
266
"""%(path)s is not versioned"""
267
def __init__(self, path):
268
BzrNewError.__init__(self)
272
class PathsNotVersionedError(BzrNewError):
273
# used when reporting several paths are not versioned
274
"""Path(s) are not versioned: %(paths_as_string)s"""
276
def __init__(self, paths):
277
from bzrlib.osutils import quotefn
278
BzrNewError.__init__(self)
280
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
283
class BadFileKindError(BzrError):
284
"""Specified file is of a kind that cannot be added.
286
(For example a symlink or device file.)"""
289
class ForbiddenFileError(BzrError):
290
"""Cannot operate on a file because it is a control file."""
293
class LockError(BzrNewError):
294
"""Lock error: %(message)s"""
295
# All exceptions from the lock/unlock functions should be from
296
# this exception class. They will be translated as necessary. The
297
# original exception is available as e.original_error
299
# New code should prefer to raise specific subclasses
300
def __init__(self, message):
301
self.message = message
304
class CommitNotPossible(LockError):
305
"""A commit was attempted but we do not have a write lock open."""
310
class AlreadyCommitted(LockError):
311
"""A rollback was requested, but is not able to be accomplished."""
316
class ReadOnlyError(LockError):
317
"""A write attempt was made in a read only transaction on %(obj)s"""
318
def __init__(self, obj):
322
class OutSideTransaction(BzrNewError):
323
"""A transaction related operation was attempted after the transaction finished."""
326
class ObjectNotLocked(LockError):
327
"""%(obj)r is not locked"""
328
# this can indicate that any particular object is not locked; see also
329
# LockNotHeld which means that a particular *lock* object is not held by
330
# the caller -- perhaps they should be unified.
331
def __init__(self, obj):
335
class ReadOnlyObjectDirtiedError(ReadOnlyError):
336
"""Cannot change object %(obj)r in read only transaction"""
337
def __init__(self, obj):
341
class UnlockableTransport(LockError):
342
"""Cannot lock: transport is read only: %(transport)s"""
343
def __init__(self, transport):
344
self.transport = transport
347
class LockContention(LockError):
348
"""Could not acquire lock %(lock)s"""
349
# TODO: show full url for lock, combining the transport and relative bits?
350
def __init__(self, lock):
354
class LockBroken(LockError):
355
"""Lock was broken while still open: %(lock)s - check storage consistency!"""
356
def __init__(self, lock):
360
class LockBreakMismatch(LockError):
361
"""Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"""
362
def __init__(self, lock, holder, target):
368
class LockNotHeld(LockError):
369
"""Lock not held: %(lock)s"""
370
def __init__(self, lock):
374
class PointlessCommit(BzrNewError):
375
"""No changes to commit"""
378
class UpgradeReadonly(BzrNewError):
379
"""Upgrade URL cannot work with readonly URL's."""
382
class UpToDateFormat(BzrNewError):
383
"""The branch format %(format)s is already at the most recent format."""
385
def __init__(self, format):
386
BzrNewError.__init__(self)
391
class StrictCommitFailed(Exception):
392
"""Commit refused because there are unknowns in the tree."""
395
class NoSuchRevision(BzrError):
396
def __init__(self, branch, revision):
398
self.revision = revision
399
msg = "Branch %s has no revision %s" % (branch, revision)
400
BzrError.__init__(self, msg)
403
class HistoryMissing(BzrError):
404
def __init__(self, branch, object_type, object_id):
406
BzrError.__init__(self,
407
'%s is missing %s {%s}'
408
% (branch, object_type, object_id))
411
class DivergedBranches(BzrError):
413
def __init__(self, branch1, branch2):
414
BzrError.__init__(self, "These branches have diverged. Try merge.")
415
self.branch1 = branch1
416
self.branch2 = branch2
419
class UnrelatedBranches(BzrCommandError):
421
msg = "Branches have no common ancestor, and no base revision"\
423
BzrCommandError.__init__(self, msg)
426
class NoCommonAncestor(BzrError):
427
def __init__(self, revision_a, revision_b):
428
msg = "Revisions have no common ancestor: %s %s." \
429
% (revision_a, revision_b)
430
BzrError.__init__(self, msg)
433
class NoCommonRoot(BzrError):
434
def __init__(self, revision_a, revision_b):
435
msg = "Revisions are not derived from the same root: %s %s." \
436
% (revision_a, revision_b)
437
BzrError.__init__(self, msg)
441
class NotAncestor(BzrError):
442
def __init__(self, rev_id, not_ancestor_id):
443
msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id,
445
BzrError.__init__(self, msg)
447
self.not_ancestor_id = not_ancestor_id
450
class InstallFailed(BzrError):
451
def __init__(self, revisions):
452
msg = "Could not install revisions:\n%s" % " ,".join(revisions)
453
BzrError.__init__(self, msg)
454
self.revisions = revisions
457
class AmbiguousBase(BzrError):
458
def __init__(self, bases):
459
warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
461
msg = "The correct base is unclear, becase %s are all equally close" %\
463
BzrError.__init__(self, msg)
467
class NoCommits(BzrError):
468
def __init__(self, branch):
469
msg = "Branch %s has no commits." % branch
470
BzrError.__init__(self, msg)
473
class UnlistableStore(BzrError):
474
def __init__(self, store):
475
BzrError.__init__(self, "Store %s is not listable" % store)
479
class UnlistableBranch(BzrError):
480
def __init__(self, br):
481
BzrError.__init__(self, "Stores for branch %s are not listable" % br)
484
class BoundBranchOutOfDate(BzrNewError):
485
"""Bound branch %(branch)s is out of date with master branch %(master)s."""
486
def __init__(self, branch, master):
487
BzrNewError.__init__(self)
492
class CommitToDoubleBoundBranch(BzrNewError):
493
"""Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
494
def __init__(self, branch, master, remote):
495
BzrNewError.__init__(self)
501
class OverwriteBoundBranch(BzrNewError):
502
"""Cannot pull --overwrite to a branch which is bound %(branch)s"""
503
def __init__(self, branch):
504
BzrNewError.__init__(self)
508
class BoundBranchConnectionFailure(BzrNewError):
509
"""Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
510
def __init__(self, branch, target, error):
511
BzrNewError.__init__(self)
517
class WeaveError(BzrNewError):
518
"""Error in processing weave: %(message)s"""
520
def __init__(self, message=None):
521
BzrNewError.__init__(self)
522
self.message = message
525
class WeaveRevisionAlreadyPresent(WeaveError):
526
"""Revision {%(revision_id)s} already present in %(weave)s"""
527
def __init__(self, revision_id, weave):
529
WeaveError.__init__(self)
530
self.revision_id = revision_id
534
class WeaveRevisionNotPresent(WeaveError):
535
"""Revision {%(revision_id)s} not present in %(weave)s"""
537
def __init__(self, revision_id, weave):
538
WeaveError.__init__(self)
539
self.revision_id = revision_id
543
class WeaveFormatError(WeaveError):
544
"""Weave invariant violated: %(what)s"""
546
def __init__(self, what):
547
WeaveError.__init__(self)
551
class WeaveParentMismatch(WeaveError):
552
"""Parents are mismatched between two revisions."""
555
class WeaveInvalidChecksum(WeaveError):
556
"""Text did not match it's checksum: %(message)s"""
559
class WeaveTextDiffers(WeaveError):
560
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
562
def __init__(self, revision_id, weave_a, weave_b):
563
WeaveError.__init__(self)
564
self.revision_id = revision_id
565
self.weave_a = weave_a
566
self.weave_b = weave_b
569
class WeaveTextDiffers(WeaveError):
570
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
572
def __init__(self, revision_id, weave_a, weave_b):
573
WeaveError.__init__(self)
574
self.revision_id = revision_id
575
self.weave_a = weave_a
576
self.weave_b = weave_b
579
class VersionedFileError(BzrNewError):
580
"""Versioned file error."""
583
class RevisionNotPresent(VersionedFileError):
584
"""Revision {%(revision_id)s} not present in %(file_id)s."""
586
def __init__(self, revision_id, file_id):
587
VersionedFileError.__init__(self)
588
self.revision_id = revision_id
589
self.file_id = file_id
592
class RevisionAlreadyPresent(VersionedFileError):
593
"""Revision {%(revision_id)s} already present in %(file_id)s."""
595
def __init__(self, revision_id, file_id):
596
VersionedFileError.__init__(self)
597
self.revision_id = revision_id
598
self.file_id = file_id
601
class KnitError(BzrNewError):
605
class KnitHeaderError(KnitError):
606
"""Knit header error: %(badline)r unexpected"""
608
def __init__(self, badline):
609
KnitError.__init__(self)
610
self.badline = badline
613
class KnitCorrupt(KnitError):
614
"""Knit %(filename)s corrupt: %(how)s"""
616
def __init__(self, filename, how):
617
KnitError.__init__(self)
618
self.filename = filename
622
class NoSuchExportFormat(BzrNewError):
623
"""Export format %(format)r not supported"""
624
def __init__(self, format):
625
BzrNewError.__init__(self)
629
class TransportError(BzrError):
630
"""All errors thrown by Transport implementations should derive
633
def __init__(self, msg=None, orig_error=None):
634
if msg is None and orig_error is not None:
635
msg = str(orig_error)
636
BzrError.__init__(self, msg)
638
self.orig_error = orig_error
641
# A set of semi-meaningful errors which can be thrown
642
class TransportNotPossible(TransportError):
643
"""This is for transports where a specific function is explicitly not
644
possible. Such as pushing files to an HTTP server.
649
class ConnectionError(TransportError):
650
"""A connection problem prevents file retrieval.
651
This does not indicate whether the file exists or not; it indicates that a
652
precondition for requesting the file was not met.
654
def __init__(self, msg=None, orig_error=None):
655
TransportError.__init__(self, msg=msg, orig_error=orig_error)
658
class ConnectionReset(TransportError):
659
"""The connection has been closed."""
663
class ConflictsInTree(BzrError):
665
BzrError.__init__(self, "Working tree has conflicts.")
668
class ParseConfigError(BzrError):
669
def __init__(self, errors, filename):
672
message = "Error(s) parsing config file %s:\n%s" % \
673
(filename, ('\n'.join(e.message for e in errors)))
674
BzrError.__init__(self, message)
677
class SigningFailed(BzrError):
678
def __init__(self, command_line):
679
BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
683
class WorkingTreeNotRevision(BzrError):
684
def __init__(self, tree):
685
BzrError.__init__(self, "The working tree for %s has changed since"
686
" last commit, but weave merge requires that it be"
687
" unchanged." % tree.basedir)
690
class CantReprocessAndShowBase(BzrNewError):
691
"""Can't reprocess and show base.
692
Reprocessing obscures relationship of conflicting lines to base."""
695
class GraphCycleError(BzrNewError):
696
"""Cycle in graph %(graph)r"""
697
def __init__(self, graph):
698
BzrNewError.__init__(self)
702
class NotConflicted(BzrNewError):
703
"""File %(filename)s is not conflicted."""
705
def __init__(self, filename):
706
BzrNewError.__init__(self)
707
self.filename = filename
710
class MustUseDecorated(Exception):
711
"""A decorating function has requested its original command be used.
713
This should never escape bzr, so does not need to be printable.
717
class MissingText(BzrNewError):
718
"""Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
720
def __init__(self, branch, text_revision, file_id):
721
BzrNewError.__init__(self)
723
self.base = branch.base
724
self.text_revision = text_revision
725
self.file_id = file_id
728
class DuplicateKey(BzrNewError):
729
"""Key %(key)s is already present in map"""
732
class MalformedTransform(BzrNewError):
733
"""Tree transform is malformed %(conflicts)r"""
736
class BzrBadParameter(BzrNewError):
737
"""A bad parameter : %(param)s is not usable.
739
This exception should never be thrown, but it is a base class for all
740
parameter-to-function errors.
742
def __init__(self, param):
743
BzrNewError.__init__(self)
747
class BzrBadParameterNotUnicode(BzrBadParameter):
748
"""Parameter %(param)s is neither unicode nor utf8."""
751
class ReusingTransform(BzrNewError):
752
"""Attempt to reuse a transform that has already been applied."""
755
class CantMoveRoot(BzrNewError):
756
"""Moving the root directory is not supported at this time"""
759
class BzrBadParameterNotString(BzrBadParameter):
760
"""Parameter %(param)s is not a string or unicode string."""
763
class BzrBadParameterMissing(BzrBadParameter):
764
"""Parameter $(param)s is required but not present."""
767
class BzrBadParameterUnicode(BzrBadParameter):
768
"""Parameter %(param) is unicode by only byte-strings are permitted."""
771
class BzrBadParameterContainsNewline(BzrBadParameter):
772
"""Parameter %(param) contains a newline."""
775
class DependencyNotPresent(BzrNewError):
776
"""Unable to import library "%(library)s": %(error)s"""
778
def __init__(self, library, error):
779
BzrNewError.__init__(self, library=library, error=error)
782
class ParamikoNotPresent(DependencyNotPresent):
783
"""Unable to import paramiko (required for sftp support): %(error)s"""
785
def __init__(self, error):
786
DependencyNotPresent.__init__(self, 'paramiko', error)
789
class UninitializableFormat(BzrNewError):
790
"""Format %(format)s cannot be initialised by this version of bzr."""
792
def __init__(self, format):
793
BzrNewError.__init__(self)
797
class NoDiff3(BzrNewError):
798
"""Diff3 is not installed on this machine."""
801
class ExistingLimbo(BzrNewError):
802
"""This tree contains left-over files from a failed operation.
803
Please examine %(limbo_dir)s to see if it contains any files you wish to
804
keep, and delete it when you are done.
806
def __init__(self, limbo_dir):
807
BzrNewError.__init__(self)
808
self.limbo_dir = limbo_dir
811
class ImmortalLimbo(BzrNewError):
812
"""Unable to delete transform temporary directory $(limbo_dir)s.
813
Please examine %(limbo_dir)s to see if it contains any files you wish to
814
keep, and delete it when you are done.
816
def __init__(self, limbo_dir):
817
BzrNewError.__init__(self)
818
self.limbo_dir = limbo_dir
821
class OutOfDateTree(BzrNewError):
822
"""Working tree is out of date, please run 'bzr update'."""
824
def __init__(self, tree):
825
BzrNewError.__init__(self)
829
class MergeModifiedFormatError(BzrNewError):
830
"""Error in merge modified format"""
833
class ConflictFormatError(BzrNewError):
834
"""Format error in conflict listings"""
837
class CorruptRepository(BzrNewError):
838
"""An error has been detected in the repository %(repo_path)s.
839
Please run bzr reconcile on this repository."""
841
def __init__(self, repo):
842
BzrNewError.__init__(self)
843
self.repo_path = repo.bzrdir.root_transport.base
846
class UpgradeRequired(BzrNewError):
847
"""To use this feature you must upgrade your branch at %(path)s."""
849
def __init__(self, path):
850
BzrNewError.__init__(self)
854
class LocalRequiresBoundBranch(BzrNewError):
855
"""Cannot perform local-only commits on unbound branches."""
858
class MissingProgressBarFinish(BzrNewError):
859
"""A nested progress bar was not 'finished' correctly."""
862
class UnsupportedOperation(BzrNewError):
863
"""The method %(mname)s is not supported on objects of type %(tname)s."""
864
def __init__(self, method, method_self):
866
self.mname = method.__name__
867
self.tname = type(method_self).__name__