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 BadFileKindError(BzrError):
273
"""Specified file is of a kind that cannot be added.
275
(For example a symlink or device file.)"""
278
class ForbiddenFileError(BzrError):
279
"""Cannot operate on a file because it is a control file."""
282
class LockError(BzrNewError):
283
"""Lock error: %(message)s"""
284
# All exceptions from the lock/unlock functions should be from
285
# this exception class. They will be translated as necessary. The
286
# original exception is available as e.original_error
288
# New code should prefer to raise specific subclasses
289
def __init__(self, message):
290
self.message = message
293
class CommitNotPossible(LockError):
294
"""A commit was attempted but we do not have a write lock open."""
299
class AlreadyCommitted(LockError):
300
"""A rollback was requested, but is not able to be accomplished."""
305
class ReadOnlyError(LockError):
306
"""A write attempt was made in a read only transaction on %(obj)s"""
307
def __init__(self, obj):
311
class OutSideTransaction(BzrNewError):
312
"""A transaction related operation was attempted after the transaction finished."""
315
class ObjectNotLocked(LockError):
316
"""%(obj)r is not locked"""
317
# this can indicate that any particular object is not locked; see also
318
# LockNotHeld which means that a particular *lock* object is not held by
319
# the caller -- perhaps they should be unified.
320
def __init__(self, obj):
324
class ReadOnlyObjectDirtiedError(ReadOnlyError):
325
"""Cannot change object %(obj)r in read only transaction"""
326
def __init__(self, obj):
330
class UnlockableTransport(LockError):
331
"""Cannot lock: transport is read only: %(transport)s"""
332
def __init__(self, transport):
333
self.transport = transport
336
class LockContention(LockError):
337
"""Could not acquire lock %(lock)s"""
338
# TODO: show full url for lock, combining the transport and relative bits?
339
def __init__(self, lock):
343
class LockBroken(LockError):
344
"""Lock was broken while still open: %(lock)s - check storage consistency!"""
345
def __init__(self, lock):
349
class LockBreakMismatch(LockError):
350
"""Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"""
351
def __init__(self, lock, holder, target):
357
class LockNotHeld(LockError):
358
"""Lock not held: %(lock)s"""
359
def __init__(self, lock):
363
class PointlessCommit(BzrNewError):
364
"""No changes to commit"""
367
class UpgradeReadonly(BzrNewError):
368
"""Upgrade URL cannot work with readonly URL's."""
371
class UpToDateFormat(BzrNewError):
372
"""The branch format %(format)s is already at the most recent format."""
374
def __init__(self, format):
375
BzrNewError.__init__(self)
380
class StrictCommitFailed(Exception):
381
"""Commit refused because there are unknowns in the tree."""
384
class NoSuchRevision(BzrError):
385
def __init__(self, branch, revision):
387
self.revision = revision
388
msg = "Branch %s has no revision %s" % (branch, revision)
389
BzrError.__init__(self, msg)
392
class HistoryMissing(BzrError):
393
def __init__(self, branch, object_type, object_id):
395
BzrError.__init__(self,
396
'%s is missing %s {%s}'
397
% (branch, object_type, object_id))
400
class DivergedBranches(BzrError):
402
def __init__(self, branch1, branch2):
403
BzrError.__init__(self, "These branches have diverged. Try merge.")
404
self.branch1 = branch1
405
self.branch2 = branch2
408
class UnrelatedBranches(BzrCommandError):
410
msg = "Branches have no common ancestor, and no base revision"\
412
BzrCommandError.__init__(self, msg)
415
class NoCommonAncestor(BzrError):
416
def __init__(self, revision_a, revision_b):
417
msg = "Revisions have no common ancestor: %s %s." \
418
% (revision_a, revision_b)
419
BzrError.__init__(self, msg)
422
class NoCommonRoot(BzrError):
423
def __init__(self, revision_a, revision_b):
424
msg = "Revisions are not derived from the same root: %s %s." \
425
% (revision_a, revision_b)
426
BzrError.__init__(self, msg)
430
class NotAncestor(BzrError):
431
def __init__(self, rev_id, not_ancestor_id):
432
msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id,
434
BzrError.__init__(self, msg)
436
self.not_ancestor_id = not_ancestor_id
439
class InstallFailed(BzrError):
440
def __init__(self, revisions):
441
msg = "Could not install revisions:\n%s" % " ,".join(revisions)
442
BzrError.__init__(self, msg)
443
self.revisions = revisions
446
class AmbiguousBase(BzrError):
447
def __init__(self, bases):
448
warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
450
msg = "The correct base is unclear, becase %s are all equally close" %\
452
BzrError.__init__(self, msg)
456
class NoCommits(BzrError):
457
def __init__(self, branch):
458
msg = "Branch %s has no commits." % branch
459
BzrError.__init__(self, msg)
462
class UnlistableStore(BzrError):
463
def __init__(self, store):
464
BzrError.__init__(self, "Store %s is not listable" % store)
468
class UnlistableBranch(BzrError):
469
def __init__(self, br):
470
BzrError.__init__(self, "Stores for branch %s are not listable" % br)
473
class BoundBranchOutOfDate(BzrNewError):
474
"""Bound branch %(branch)s is out of date with master branch %(master)s."""
475
def __init__(self, branch, master):
476
BzrNewError.__init__(self)
481
class CommitToDoubleBoundBranch(BzrNewError):
482
"""Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
483
def __init__(self, branch, master, remote):
484
BzrNewError.__init__(self)
490
class OverwriteBoundBranch(BzrNewError):
491
"""Cannot pull --overwrite to a branch which is bound %(branch)s"""
492
def __init__(self, branch):
493
BzrNewError.__init__(self)
497
class BoundBranchConnectionFailure(BzrNewError):
498
"""Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
499
def __init__(self, branch, target, error):
500
BzrNewError.__init__(self)
506
class WeaveError(BzrNewError):
507
"""Error in processing weave: %(message)s"""
509
def __init__(self, message=None):
510
BzrNewError.__init__(self)
511
self.message = message
514
class WeaveRevisionAlreadyPresent(WeaveError):
515
"""Revision {%(revision_id)s} already present in %(weave)s"""
516
def __init__(self, revision_id, weave):
518
WeaveError.__init__(self)
519
self.revision_id = revision_id
523
class WeaveRevisionNotPresent(WeaveError):
524
"""Revision {%(revision_id)s} not present in %(weave)s"""
526
def __init__(self, revision_id, weave):
527
WeaveError.__init__(self)
528
self.revision_id = revision_id
532
class WeaveFormatError(WeaveError):
533
"""Weave invariant violated: %(what)s"""
535
def __init__(self, what):
536
WeaveError.__init__(self)
540
class WeaveParentMismatch(WeaveError):
541
"""Parents are mismatched between two revisions."""
544
class WeaveInvalidChecksum(WeaveError):
545
"""Text did not match it's checksum: %(message)s"""
548
class WeaveTextDiffers(WeaveError):
549
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
551
def __init__(self, revision_id, weave_a, weave_b):
552
WeaveError.__init__(self)
553
self.revision_id = revision_id
554
self.weave_a = weave_a
555
self.weave_b = weave_b
558
class WeaveTextDiffers(WeaveError):
559
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
561
def __init__(self, revision_id, weave_a, weave_b):
562
WeaveError.__init__(self)
563
self.revision_id = revision_id
564
self.weave_a = weave_a
565
self.weave_b = weave_b
568
class VersionedFileError(BzrNewError):
569
"""Versioned file error."""
572
class RevisionNotPresent(VersionedFileError):
573
"""Revision {%(revision_id)s} not present in %(file_id)s."""
575
def __init__(self, revision_id, file_id):
576
VersionedFileError.__init__(self)
577
self.revision_id = revision_id
578
self.file_id = file_id
581
class RevisionAlreadyPresent(VersionedFileError):
582
"""Revision {%(revision_id)s} already present in %(file_id)s."""
584
def __init__(self, revision_id, file_id):
585
VersionedFileError.__init__(self)
586
self.revision_id = revision_id
587
self.file_id = file_id
590
class KnitError(BzrNewError):
594
class KnitHeaderError(KnitError):
595
"""Knit header error: %(badline)r unexpected"""
597
def __init__(self, badline):
598
KnitError.__init__(self)
599
self.badline = badline
602
class KnitCorrupt(KnitError):
603
"""Knit %(filename)s corrupt: %(how)s"""
605
def __init__(self, filename, how):
606
KnitError.__init__(self)
607
self.filename = filename
611
class NoSuchExportFormat(BzrNewError):
612
"""Export format %(format)r not supported"""
613
def __init__(self, format):
614
BzrNewError.__init__(self)
618
class TransportError(BzrError):
619
"""All errors thrown by Transport implementations should derive
622
def __init__(self, msg=None, orig_error=None):
623
if msg is None and orig_error is not None:
624
msg = str(orig_error)
625
BzrError.__init__(self, msg)
627
self.orig_error = orig_error
630
# A set of semi-meaningful errors which can be thrown
631
class TransportNotPossible(TransportError):
632
"""This is for transports where a specific function is explicitly not
633
possible. Such as pushing files to an HTTP server.
638
class ConnectionError(TransportError):
639
"""A connection problem prevents file retrieval.
640
This does not indicate whether the file exists or not; it indicates that a
641
precondition for requesting the file was not met.
643
def __init__(self, msg=None, orig_error=None):
644
TransportError.__init__(self, msg=msg, orig_error=orig_error)
647
class ConnectionReset(TransportError):
648
"""The connection has been closed."""
652
class ConflictsInTree(BzrError):
654
BzrError.__init__(self, "Working tree has conflicts.")
657
class ParseConfigError(BzrError):
658
def __init__(self, errors, filename):
661
message = "Error(s) parsing config file %s:\n%s" % \
662
(filename, ('\n'.join(e.message for e in errors)))
663
BzrError.__init__(self, message)
666
class SigningFailed(BzrError):
667
def __init__(self, command_line):
668
BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
672
class WorkingTreeNotRevision(BzrError):
673
def __init__(self, tree):
674
BzrError.__init__(self, "The working tree for %s has changed since"
675
" last commit, but weave merge requires that it be"
676
" unchanged." % tree.basedir)
679
class CantReprocessAndShowBase(BzrNewError):
680
"""Can't reprocess and show base.
681
Reprocessing obscures relationship of conflicting lines to base."""
684
class GraphCycleError(BzrNewError):
685
"""Cycle in graph %(graph)r"""
686
def __init__(self, graph):
687
BzrNewError.__init__(self)
691
class NotConflicted(BzrNewError):
692
"""File %(filename)s is not conflicted."""
694
def __init__(self, filename):
695
BzrNewError.__init__(self)
696
self.filename = filename
699
class MustUseDecorated(Exception):
700
"""A decorating function has requested its original command be used.
702
This should never escape bzr, so does not need to be printable.
706
class MissingText(BzrNewError):
707
"""Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
709
def __init__(self, branch, text_revision, file_id):
710
BzrNewError.__init__(self)
712
self.base = branch.base
713
self.text_revision = text_revision
714
self.file_id = file_id
717
class DuplicateKey(BzrNewError):
718
"""Key %(key)s is already present in map"""
721
class MalformedTransform(BzrNewError):
722
"""Tree transform is malformed %(conflicts)r"""
725
class BzrBadParameter(BzrNewError):
726
"""A bad parameter : %(param)s is not usable.
728
This exception should never be thrown, but it is a base class for all
729
parameter-to-function errors.
731
def __init__(self, param):
732
BzrNewError.__init__(self)
736
class BzrBadParameterNotUnicode(BzrBadParameter):
737
"""Parameter %(param)s is neither unicode nor utf8."""
740
class ReusingTransform(BzrNewError):
741
"""Attempt to reuse a transform that has already been applied."""
744
class CantMoveRoot(BzrNewError):
745
"""Moving the root directory is not supported at this time"""
748
class BzrBadParameterNotString(BzrBadParameter):
749
"""Parameter %(param)s is not a string or unicode string."""
752
class BzrBadParameterMissing(BzrBadParameter):
753
"""Parameter $(param)s is required but not present."""
756
class DependencyNotPresent(BzrNewError):
757
"""Unable to import library "%(library)s": %(error)s"""
759
def __init__(self, library, error):
760
BzrNewError.__init__(self, library=library, error=error)
763
class ParamikoNotPresent(DependencyNotPresent):
764
"""Unable to import paramiko (required for sftp support): %(error)s"""
766
def __init__(self, error):
767
DependencyNotPresent.__init__(self, 'paramiko', error)
770
class UninitializableFormat(BzrNewError):
771
"""Format %(format)s cannot be initialised by this version of bzr."""
773
def __init__(self, format):
774
BzrNewError.__init__(self)
778
class NoDiff3(BzrNewError):
779
"""Diff3 is not installed on this machine."""
782
class ExistingLimbo(BzrNewError):
783
"""This tree contains left-over files from a failed operation.
784
Please examine %(limbo_dir)s to see if it contains any files you wish to
785
keep, and delete it when you are done.
787
def __init__(self, limbo_dir):
788
BzrNewError.__init__(self)
789
self.limbo_dir = limbo_dir
792
class ImmortalLimbo(BzrNewError):
793
"""Unable to delete transform temporary directory $(limbo_dir)s.
794
Please examine %(limbo_dir)s to see if it contains any files you wish to
795
keep, and delete it when you are done.
797
def __init__(self, limbo_dir):
798
BzrNewError.__init__(self)
799
self.limbo_dir = limbo_dir
802
class OutOfDateTree(BzrNewError):
803
"""Working tree is out of date, please run 'bzr update'."""
805
def __init__(self, tree):
806
BzrNewError.__init__(self)
810
class MergeModifiedFormatError(BzrNewError):
811
"""Error in merge modified format"""
814
class ConflictFormatError(BzrNewError):
815
"""Format error in conflict listings"""
818
class CorruptRepository(BzrNewError):
819
"""An error has been detected in the repository %(repo_path)s.
820
Please run bzr reconcile on this repository."""
822
def __init__(self, repo):
823
BzrNewError.__init__(self)
824
self.repo_path = repo.bzrdir.root_transport.base
827
class UpgradeRequired(BzrNewError):
828
"""To use this feature you must upgrade your branch at %(path)s."""
830
def __init__(self, path):
831
BzrNewError.__init__(self)
835
class LocalRequiresBoundBranch(BzrNewError):
836
"""Cannot perform local-only commits on unbound branches."""
839
class MissingProgressBarFinish(BzrNewError):
840
"""A nested progress bar was not 'finished' correctly."""
843
class UnsupportedOperation(BzrNewError):
844
"""The method %(mname)s is not supported on objects of type %(tname)s."""
845
def __init__(self, method, method_self):
847
self.mname = method.__name__
848
self.tname = type(method_self).__name__