1
# Copyright (C) 2005, 2006 Canonical
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU General Public License for more details.
13
13
# You should have received a copy of the GNU General Public License
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
17
"""Exceptions for bzr, and reporting of them.
19
There are 3 different classes of error:
21
* KeyboardInterrupt, and OSError with EPIPE - the program terminates
22
with an appropriate short message
24
* User errors, indicating a problem caused by the user such as a bad URL.
25
These are printed in a short form.
27
* Internal unexpected errors, including most Python builtin errors
28
and some raised from inside bzr. These are printed with a full
29
traceback and an invitation to report the bug.
19
31
Exceptions are caught at a high level to report errors to the user, and
20
32
might also be caught inside the program. Therefore it needs to be
21
33
possible to convert them to a meaningful string, and also for them to be
127
167
class InvalidRevisionId(BzrNewError):
128
168
"""Invalid revision-id {%(revision_id)s} in %(branch)s"""
129
170
def __init__(self, revision_id, branch):
171
# branch can be any string or object with __str__ defined
130
172
BzrNewError.__init__(self)
131
173
self.revision_id = revision_id
132
174
self.branch = branch
135
177
class NoWorkingTree(BzrNewError):
136
"""No WorkingTree exists for %s(base)."""
178
"""No WorkingTree exists for %(base)s."""
138
180
def __init__(self, base):
139
181
BzrNewError.__init__(self)
143
class BzrCommandError(BzrError):
144
# Error from malformed user command
145
# This is being misused as a generic exception
146
# pleae subclass. RBC 20051030
185
class NotLocalUrl(BzrNewError):
186
"""%(url)s is not a local path."""
188
def __init__(self, url):
189
BzrNewError.__init__(self)
193
class BzrCommandError(BzrNewError):
194
"""Error from user command"""
198
# Error from malformed user command; please avoid raising this as a
199
# generic exception not caused by user input.
148
201
# I think it's a waste of effort to differentiate between errors that
149
202
# are not intended to be caught anyway. UI code need not subclass
150
203
# BzrCommandError, and non-UI code should not throw a subclass of
151
204
# BzrCommandError. ADHB 20051211
205
def __init__(self, msg):
206
# Object.__str__() must return a real string
207
# returning a Unicode string is a python error.
208
if isinstance(msg, unicode):
209
self.msg = msg.encode('utf8')
152
213
def __str__(self):
156
217
class BzrOptionError(BzrCommandError):
157
"""Some missing or otherwise incorrect option was supplied."""
218
"""Error in command line options"""
160
class StrictCommitFailed(Exception):
161
"""Commit refused because there are unknowns in the tree."""
221
class StrictCommitFailed(BzrNewError):
222
"""Commit refused because there are unknown files in the tree"""
225
# XXX: Should be unified with TransportError; they seem to represent the
164
227
class PathError(BzrNewError):
165
228
"""Generic path error: %(path)r%(extra)s)"""
166
230
def __init__(self, path, extra=None):
167
231
BzrNewError.__init__(self)
199
class NotBranchError(BzrNewError):
294
class InvalidNormalization(PathError):
295
"""Path %(path)r is not unicode normalized"""
298
# TODO: This is given a URL; we try to unescape it but doing that from inside
299
# the exception object is a bit undesirable.
300
# TODO: Probably this behavior of should be a common superclass
301
class NotBranchError(PathError):
200
302
"""Not a branch: %(path)s"""
201
304
def __init__(self, path):
305
import bzrlib.urlutils as urlutils
306
self.path = urlutils.unescape_for_display(path, 'ascii')
309
class AlreadyBranchError(PathError):
310
"""Already a branch: %(path)s."""
313
class BranchExistsWithoutWorkingTree(PathError):
314
"""Directory contains a branch, but no working tree \
315
(use bzr checkout if you wish to build a working tree): %(path)s"""
318
class AtomicFileAlreadyClosed(PathError):
319
"""'%(function)s' called on an AtomicFile after it was closed: %(path)s"""
321
def __init__(self, path, function):
322
PathError.__init__(self, path=path, extra=None)
323
self.function = function
326
class InaccessibleParent(PathError):
327
"""Parent not accessible given base %(base)s and relative path %(path)s"""
329
def __init__(self, path, base):
330
PathError.__init__(self, path)
334
class NoRepositoryPresent(BzrNewError):
335
"""No repository present: %(path)r"""
336
def __init__(self, bzrdir):
202
337
BzrNewError.__init__(self)
338
self.path = bzrdir.transport.clone('..').base
206
341
class FileInWrongBranch(BzrNewError):
207
342
"""File %(path)s in not in branch %(branch_base)s."""
208
344
def __init__(self, branch, path):
209
345
BzrNewError.__init__(self)
210
346
self.branch = branch
228
class BadFileKindError(BzrError):
229
"""Specified file is of a kind that cannot be added.
231
(For example a symlink or device file.)"""
234
class ForbiddenFileError(BzrError):
235
"""Cannot operate on a file because it is a control file."""
238
class LockError(Exception):
375
class PathsNotVersionedError(BzrNewError):
376
# used when reporting several paths are not versioned
377
"""Path(s) are not versioned: %(paths_as_string)s"""
379
def __init__(self, paths):
380
from bzrlib.osutils import quotefn
381
BzrNewError.__init__(self)
383
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
386
class PathsDoNotExist(BzrNewError):
387
"""Path(s) do not exist: %(paths_as_string)s"""
389
# used when reporting that paths are neither versioned nor in the working
392
def __init__(self, paths):
394
from bzrlib.osutils import quotefn
395
BzrNewError.__init__(self)
397
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
400
class BadFileKindError(BzrNewError):
401
"""Cannot operate on %(filename)s of unsupported kind %(kind)s"""
404
class ForbiddenControlFileError(BzrNewError):
405
"""Cannot operate on %(filename)s because it is a control file"""
408
class LockError(BzrNewError):
409
"""Lock error: %(message)s"""
240
410
# All exceptions from the lock/unlock functions should be from
241
411
# this exception class. They will be translated as necessary. The
242
412
# original exception is available as e.original_error
414
# New code should prefer to raise specific subclasses
415
def __init__(self, message):
416
self.message = message
245
419
class CommitNotPossible(LockError):
246
420
"""A commit was attempted but we do not have a write lock open."""
249
425
class AlreadyCommitted(LockError):
250
426
"""A rollback was requested, but is not able to be accomplished."""
253
431
class ReadOnlyError(LockError):
254
"""A write attempt was made in a read only transaction."""
432
"""A write attempt was made in a read only transaction on %(obj)s"""
433
def __init__(self, obj):
437
class OutSideTransaction(BzrNewError):
438
"""A transaction related operation was attempted after the transaction finished."""
441
class ObjectNotLocked(LockError):
442
"""%(obj)r is not locked"""
444
is_user_error = False
446
# this can indicate that any particular object is not locked; see also
447
# LockNotHeld which means that a particular *lock* object is not held by
448
# the caller -- perhaps they should be unified.
449
def __init__(self, obj):
453
class ReadOnlyObjectDirtiedError(ReadOnlyError):
454
"""Cannot change object %(obj)r in read only transaction"""
455
def __init__(self, obj):
459
class UnlockableTransport(LockError):
460
"""Cannot lock: transport is read only: %(transport)s"""
461
def __init__(self, transport):
462
self.transport = transport
465
class LockContention(LockError):
466
"""Could not acquire lock %(lock)s"""
467
# TODO: show full url for lock, combining the transport and relative bits?
468
def __init__(self, lock):
472
class LockBroken(LockError):
473
"""Lock was broken while still open: %(lock)s - check storage consistency!"""
474
def __init__(self, lock):
478
class LockBreakMismatch(LockError):
479
"""Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"""
480
def __init__(self, lock, holder, target):
486
class LockNotHeld(LockError):
487
"""Lock not held: %(lock)s"""
488
def __init__(self, lock):
257
492
class PointlessCommit(BzrNewError):
258
493
"""No changes to commit"""
496
class UpgradeReadonly(BzrNewError):
497
"""Upgrade URL cannot work with readonly URL's."""
500
class UpToDateFormat(BzrNewError):
501
"""The branch format %(format)s is already at the most recent format."""
503
def __init__(self, format):
504
BzrNewError.__init__(self)
260
509
class StrictCommitFailed(Exception):
261
510
"""Commit refused because there are unknowns in the tree."""
263
class NoSuchRevision(BzrError):
513
class NoSuchRevision(BzrNewError):
514
"""Branch %(branch)s has no revision %(revision)s"""
516
is_user_error = False
264
518
def __init__(self, branch, revision):
265
519
self.branch = branch
266
520
self.revision = revision
267
msg = "Branch %s has no revision %s" % (branch, revision)
268
BzrError.__init__(self, msg)
271
523
class HistoryMissing(BzrError):
276
528
% (branch, object_type, object_id))
279
class DivergedBranches(BzrError):
531
class DivergedBranches(BzrNewError):
532
"These branches have diverged. Use the merge command to reconcile them."""
280
536
def __init__(self, branch1, branch2):
281
BzrError.__init__(self, "These branches have diverged. Try merge.")
282
537
self.branch1 = branch1
283
538
self.branch2 = branch2
286
class UnrelatedBranches(BzrCommandError):
288
msg = "Branches have no common ancestor, and no base revision"\
290
BzrCommandError.__init__(self, msg)
292
class NoCommonAncestor(BzrError):
541
class UnrelatedBranches(BzrNewError):
542
"Branches have no common ancestor, and no merge base revision was specified."
547
class NoCommonAncestor(BzrNewError):
548
"Revisions have no common ancestor: %(revision_a)s %(revision_b)s"
293
550
def __init__(self, revision_a, revision_b):
294
msg = "Revisions have no common ancestor: %s %s." \
295
% (revision_a, revision_b)
296
BzrError.__init__(self, msg)
551
self.revision_a = revision_a
552
self.revision_b = revision_b
298
555
class NoCommonRoot(BzrError):
299
556
def __init__(self, revision_a, revision_b):
320
579
class AmbiguousBase(BzrError):
321
580
def __init__(self, bases):
322
msg = "The correct base is unclear, becase %s are all equally close" %\
581
warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
583
msg = "The correct base is unclear, because %s are all equally close" %\
324
585
BzrError.__init__(self, msg)
325
586
self.bases = bases
327
589
class NoCommits(BzrError):
328
590
def __init__(self, branch):
329
591
msg = "Branch %s has no commits." % branch
330
592
BzrError.__init__(self, msg)
332
595
class UnlistableStore(BzrError):
333
596
def __init__(self, store):
334
597
BzrError.__init__(self, "Store %s is not listable" % store)
336
601
class UnlistableBranch(BzrError):
337
602
def __init__(self, br):
338
603
BzrError.__init__(self, "Stores for branch %s are not listable" % br)
606
class BoundBranchOutOfDate(BzrNewError):
607
"""Bound branch %(branch)s is out of date with master branch %(master)s."""
608
def __init__(self, branch, master):
609
BzrNewError.__init__(self)
614
class CommitToDoubleBoundBranch(BzrNewError):
615
"""Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
616
def __init__(self, branch, master, remote):
617
BzrNewError.__init__(self)
623
class OverwriteBoundBranch(BzrNewError):
624
"""Cannot pull --overwrite to a branch which is bound %(branch)s"""
625
def __init__(self, branch):
626
BzrNewError.__init__(self)
630
class BoundBranchConnectionFailure(BzrNewError):
631
"""Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
632
def __init__(self, branch, target, error):
633
BzrNewError.__init__(self)
341
639
class WeaveError(BzrNewError):
342
640
"""Error in processing weave: %(message)s"""
343
642
def __init__(self, message=None):
344
643
BzrNewError.__init__(self)
345
644
self.message = message
376
678
"""Text did not match it's checksum: %(message)s"""
681
class WeaveTextDiffers(WeaveError):
682
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
684
def __init__(self, revision_id, weave_a, weave_b):
685
WeaveError.__init__(self)
686
self.revision_id = revision_id
687
self.weave_a = weave_a
688
self.weave_b = weave_b
691
class WeaveTextDiffers(WeaveError):
692
"""Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
694
def __init__(self, revision_id, weave_a, weave_b):
695
WeaveError.__init__(self)
696
self.revision_id = revision_id
697
self.weave_a = weave_a
698
self.weave_b = weave_b
701
class VersionedFileError(BzrNewError):
702
"""Versioned file error."""
705
class RevisionNotPresent(VersionedFileError):
706
"""Revision {%(revision_id)s} not present in %(file_id)s."""
708
def __init__(self, revision_id, file_id):
709
VersionedFileError.__init__(self)
710
self.revision_id = revision_id
711
self.file_id = file_id
714
class RevisionAlreadyPresent(VersionedFileError):
715
"""Revision {%(revision_id)s} already present in %(file_id)s."""
717
def __init__(self, revision_id, file_id):
718
VersionedFileError.__init__(self)
719
self.revision_id = revision_id
720
self.file_id = file_id
723
class KnitError(BzrNewError):
727
class KnitHeaderError(KnitError):
728
"""Knit header error: %(badline)r unexpected"""
730
def __init__(self, badline):
731
KnitError.__init__(self)
732
self.badline = badline
735
class KnitCorrupt(KnitError):
736
"""Knit %(filename)s corrupt: %(how)s"""
738
def __init__(self, filename, how):
739
KnitError.__init__(self)
740
self.filename = filename
379
744
class NoSuchExportFormat(BzrNewError):
380
745
"""Export format %(format)r not supported"""
381
746
def __init__(self, format):
383
748
self.format = format
386
class TransportError(BzrError):
387
"""All errors thrown by Transport implementations should derive
751
class TransportError(BzrNewError):
752
"""Transport error: %(msg)s %(orig_error)s"""
390
754
def __init__(self, msg=None, orig_error=None):
391
755
if msg is None and orig_error is not None:
392
756
msg = str(orig_error)
393
BzrError.__init__(self, msg)
757
if orig_error is None:
395
762
self.orig_error = orig_error
763
BzrNewError.__init__(self)
397
766
# A set of semi-meaningful errors which can be thrown
398
767
class TransportNotPossible(TransportError):
399
"""This is for transports where a specific function is explicitly not
400
possible. Such as pushing files to an HTTP server.
768
"""Transport operation not possible: %(msg)s %(orig_error)%"""
405
771
class ConnectionError(TransportError):
406
"""A connection problem prevents file retrieval.
407
This does not indicate whether the file exists or not; it indicates that a
408
precondition for requesting the file was not met.
410
def __init__(self, msg=None, orig_error=None):
411
TransportError.__init__(self, msg=msg, orig_error=orig_error)
772
"""Connection error: %(msg)s %(orig_error)s"""
414
775
class ConnectionReset(TransportError):
415
"""The connection has been closed."""
776
"""Connection closed: %(msg)s %(orig_error)s"""
779
class InvalidRange(TransportError):
780
"""Invalid range access."""
782
def __init__(self, path, offset):
783
TransportError.__init__(self, ("Invalid range access in %s at %d"
787
class InvalidHttpResponse(TransportError):
788
"""Invalid http response for %(path)s: %(msg)s"""
790
def __init__(self, path, msg, orig_error=None):
792
TransportError.__init__(self, msg, orig_error=orig_error)
795
class InvalidHttpRange(InvalidHttpResponse):
796
"""Invalid http range "%(range)s" for %(path)s: %(msg)s"""
798
def __init__(self, path, range, msg):
800
InvalidHttpResponse.__init__(self, path, msg)
803
class InvalidHttpContentType(InvalidHttpResponse):
804
"""Invalid http Content-type "%(ctype)s" for %(path)s: %(msg)s"""
806
def __init__(self, path, ctype, msg):
808
InvalidHttpResponse.__init__(self, path, msg)
418
811
class ConflictsInTree(BzrError):
419
812
def __init__(self):
420
813
BzrError.__init__(self, "Working tree has conflicts.")
422
816
class ParseConfigError(BzrError):
423
817
def __init__(self, errors, filename):
424
818
if filename is None:
474
888
self.file_id = file_id
891
class DuplicateKey(BzrNewError):
892
"""Key %(key)s is already present in map"""
895
class MalformedTransform(BzrNewError):
896
"""Tree transform is malformed %(conflicts)r"""
477
899
class BzrBadParameter(BzrNewError):
478
"""Parameter %(param)s is neither unicode nor utf8."""
900
"""A bad parameter : %(param)s is not usable.
902
This exception should never be thrown, but it is a base class for all
903
parameter-to-function errors.
480
905
def __init__(self, param):
481
906
BzrNewError.__init__(self)
482
907
self.param = param
910
class BzrBadParameterNotUnicode(BzrBadParameter):
911
"""Parameter %(param)s is neither unicode nor utf8."""
914
class ReusingTransform(BzrNewError):
915
"""Attempt to reuse a transform that has already been applied."""
918
class CantMoveRoot(BzrNewError):
919
"""Moving the root directory is not supported at this time"""
922
class BzrBadParameterNotString(BzrBadParameter):
923
"""Parameter %(param)s is not a string or unicode string."""
926
class BzrBadParameterMissing(BzrBadParameter):
927
"""Parameter $(param)s is required but not present."""
930
class BzrBadParameterUnicode(BzrBadParameter):
931
"""Parameter %(param)s is unicode but only byte-strings are permitted."""
934
class BzrBadParameterContainsNewline(BzrBadParameter):
935
"""Parameter %(param)s contains a newline."""
938
class DependencyNotPresent(BzrNewError):
939
"""Unable to import library "%(library)s": %(error)s"""
941
def __init__(self, library, error):
942
BzrNewError.__init__(self, library=library, error=error)
945
class ParamikoNotPresent(DependencyNotPresent):
946
"""Unable to import paramiko (required for sftp support): %(error)s"""
948
def __init__(self, error):
949
DependencyNotPresent.__init__(self, 'paramiko', error)
952
class UninitializableFormat(BzrNewError):
953
"""Format %(format)s cannot be initialised by this version of bzr."""
955
def __init__(self, format):
956
BzrNewError.__init__(self)
960
class NoDiff(BzrNewError):
961
"""Diff is not installed on this machine: %(msg)s"""
963
def __init__(self, msg):
964
BzrNewError.__init__(self, msg=msg)
967
class NoDiff3(BzrNewError):
968
"""Diff3 is not installed on this machine."""
971
class ExistingLimbo(BzrNewError):
972
"""This tree contains left-over files from a failed operation.
973
Please examine %(limbo_dir)s to see if it contains any files you wish to
974
keep, and delete it when you are done.
976
def __init__(self, limbo_dir):
977
BzrNewError.__init__(self)
978
self.limbo_dir = limbo_dir
981
class ImmortalLimbo(BzrNewError):
982
"""Unable to delete transform temporary directory $(limbo_dir)s.
983
Please examine %(limbo_dir)s to see if it contains any files you wish to
984
keep, and delete it when you are done.
986
def __init__(self, limbo_dir):
987
BzrNewError.__init__(self)
988
self.limbo_dir = limbo_dir
991
class OutOfDateTree(BzrNewError):
992
"""Working tree is out of date, please run 'bzr update'."""
994
def __init__(self, tree):
995
BzrNewError.__init__(self)
999
class MergeModifiedFormatError(BzrNewError):
1000
"""Error in merge modified format"""
1003
class ConflictFormatError(BzrNewError):
1004
"""Format error in conflict listings"""
1007
class CorruptRepository(BzrNewError):
1008
"""An error has been detected in the repository %(repo_path)s.
1009
Please run bzr reconcile on this repository."""
1011
def __init__(self, repo):
1012
BzrNewError.__init__(self)
1013
self.repo_path = repo.bzrdir.root_transport.base
1016
class UpgradeRequired(BzrNewError):
1017
"""To use this feature you must upgrade your branch at %(path)s."""
1019
def __init__(self, path):
1020
BzrNewError.__init__(self)
1024
class LocalRequiresBoundBranch(BzrNewError):
1025
"""Cannot perform local-only commits on unbound branches."""
1028
class MissingProgressBarFinish(BzrNewError):
1029
"""A nested progress bar was not 'finished' correctly."""
1032
class InvalidProgressBarType(BzrNewError):
1033
"""Environment variable BZR_PROGRESS_BAR='%(bar_type)s is not a supported type
1034
Select one of: %(valid_types)s"""
1036
def __init__(self, bar_type, valid_types):
1037
BzrNewError.__init__(self, bar_type=bar_type, valid_types=valid_types)
1040
class UnsupportedOperation(BzrNewError):
1041
"""The method %(mname)s is not supported on objects of type %(tname)s."""
1042
def __init__(self, method, method_self):
1043
self.method = method
1044
self.mname = method.__name__
1045
self.tname = type(method_self).__name__
1048
class BinaryFile(BzrNewError):
1049
"""File is binary but should be text."""
1052
class IllegalPath(BzrNewError):
1053
"""The path %(path)s is not permitted on this platform"""
1055
def __init__(self, path):
1056
BzrNewError.__init__(self)
1060
class TestamentMismatch(BzrNewError):
1061
"""Testament did not match expected value.
1062
For revision_id {%(revision_id)s}, expected {%(expected)s}, measured
1065
def __init__(self, revision_id, expected, measured):
1066
self.revision_id = revision_id
1067
self.expected = expected
1068
self.measured = measured
1071
class NotABundle(BzrNewError):
1072
"""Not a bzr revision-bundle: %(text)r"""
1074
def __init__(self, text):
1075
BzrNewError.__init__(self)
1079
class BadBundle(BzrNewError):
1080
"""Bad bzr revision-bundle: %(text)r"""
1082
def __init__(self, text):
1083
BzrNewError.__init__(self)
1087
class MalformedHeader(BadBundle):
1088
"""Malformed bzr revision-bundle header: %(text)r"""
1090
def __init__(self, text):
1091
BzrNewError.__init__(self)
1095
class MalformedPatches(BadBundle):
1096
"""Malformed patches in bzr revision-bundle: %(text)r"""
1098
def __init__(self, text):
1099
BzrNewError.__init__(self)
1103
class MalformedFooter(BadBundle):
1104
"""Malformed footer in bzr revision-bundle: %(text)r"""
1106
def __init__(self, text):
1107
BzrNewError.__init__(self)
1111
class UnsupportedEOLMarker(BadBundle):
1112
"""End of line marker was not \\n in bzr revision-bundle"""
1115
BzrNewError.__init__(self)
1118
class UnknownSSH(BzrNewError):
1119
"""Unrecognised value for BZR_SSH environment variable: %(vendor)s"""
1121
def __init__(self, vendor):
1122
BzrNewError.__init__(self)
1123
self.vendor = vendor
1126
class GhostRevisionUnusableHere(BzrNewError):
1127
"""Ghost revision {%(revision_id)s} cannot be used here."""
1129
def __init__(self, revision_id):
1130
BzrNewError.__init__(self)
1131
self.revision_id = revision_id