1
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.
31
19
Exceptions are caught at a high level to report errors to the user, and
32
20
might also be caught inside the program. Therefore it needs to be
33
21
possible to convert them to a meaningful string, and also for them to be
58
46
* create a new exception class for any class of error that can be
59
usefully distinguished. If no callers are likely to want to catch
60
one but not another, don't worry about them.
62
* the __str__ method should generate something useful; BzrError provides
63
a good default implementation
65
Exception strings should start with a capital letter and should not have a
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
69
56
from warnings import warn
187
class BzrCommandError(BzrNewError):
188
"""Error from user command"""
192
# Error from malformed user command; please avoid raising this as a
193
# generic exception not caused by user input.
166
class BzrCommandError(BzrError):
167
# Error from malformed user command
168
# This is being misused as a generic exception
169
# pleae subclass. RBC 20051030
195
171
# I think it's a waste of effort to differentiate between errors that
196
172
# are not intended to be caught anyway. UI code need not subclass
197
173
# BzrCommandError, and non-UI code should not throw a subclass of
198
174
# BzrCommandError. ADHB 20051211
199
def __init__(self, msg):
202
175
def __str__(self):
206
179
class BzrOptionError(BzrCommandError):
207
"""Error in command line options"""
180
"""Some missing or otherwise incorrect option was supplied."""
210
class StrictCommitFailed(BzrNewError):
211
"""Commit refused because there are unknown files in the tree"""
183
class StrictCommitFailed(Exception):
184
"""Commit refused because there are unknowns in the tree."""
214
187
# XXX: Should be unified with TransportError; they seem to represent the
245
218
"""Permission denied: %(path)r%(extra)s"""
248
class InvalidURL(PathError):
249
"""Invalid url supplied to transport: %(path)r%(extra)s"""
252
class InvalidURLJoin(PathError):
253
"""Invalid URL join request: %(args)s%(extra)s"""
255
def __init__(self, msg, base, args):
256
PathError.__init__(self, base, msg)
258
self.args.extend(args)
261
class UnsupportedProtocol(PathError):
262
"""Unsupported protocol for url "%(path)s"%(extra)s"""
264
def __init__(self, url, extra):
265
PathError.__init__(self, url, extra=extra)
268
221
class PathNotChild(BzrNewError):
269
222
"""Path %(path)r is not a child of path %(base)r%(extra)s"""
271
is_user_error = False
273
223
def __init__(self, path, base, extra=None):
274
224
BzrNewError.__init__(self)
283
class InvalidNormalization(PathError):
284
"""Path %(path)r is not unicode normalized"""
287
# TODO: This is given a URL; we try to unescape it but doing that from inside
288
# the exception object is a bit undesirable.
289
# TODO: Probably this behavior of should be a common superclass
290
233
class NotBranchError(PathError):
291
234
"""Not a branch: %(path)s"""
293
def __init__(self, path):
294
import bzrlib.urlutils as urlutils
295
self.path = urlutils.unescape_for_display(path, 'ascii')
298
237
class AlreadyBranchError(PathError):
299
238
"""Already a branch: %(path)s."""
304
243
(use bzr checkout if you wish to build a working tree): %(path)s"""
307
class AtomicFileAlreadyClosed(PathError):
308
"""'%(function)s' called on an AtomicFile after it was closed: %(path)s"""
310
def __init__(self, path, function):
311
PathError.__init__(self, path=path, extra=None)
312
self.function = function
315
class InaccessibleParent(PathError):
316
"""Parent not accessible given base %(base)s and relative path %(path)s"""
318
def __init__(self, path, base):
319
PathError.__init__(self, path)
323
246
class NoRepositoryPresent(BzrNewError):
324
247
"""No repository present: %(path)r"""
325
248
def __init__(self, bzrdir):
340
class UnsupportedFormatError(BzrNewError):
341
"""Unsupported branch format: %(format)s"""
344
class UnknownFormatError(BzrNewError):
345
"""Unknown branch format: %(format)r"""
263
class UnsupportedFormatError(BzrError):
264
"""Specified path is a bzr branch that we recognize but cannot read."""
266
return 'unsupported branch format: %s' % self.args[0]
269
class UnknownFormatError(BzrError):
270
"""Specified path is a bzr branch whose format we do not recognize."""
272
return 'unknown branch format: %s' % self.args[0]
348
275
class IncompatibleFormat(BzrNewError):
386
313
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
389
class BadFileKindError(BzrNewError):
390
"""Cannot operate on %(filename)s of unsupported kind %(kind)s"""
393
class ForbiddenControlFileError(BzrNewError):
394
"""Cannot operate on %(filename)s because it is a control file"""
316
class BadFileKindError(BzrError):
317
"""Specified file is of a kind that cannot be added.
319
(For example a symlink or device file.)"""
322
class ForbiddenFileError(BzrError):
323
"""Cannot operate on a file because it is a control file."""
397
326
class LockError(BzrNewError):
499
425
"""Commit refused because there are unknowns in the tree."""
502
class NoSuchRevision(BzrNewError):
503
"""Branch %(branch)s has no revision %(revision)s"""
505
is_user_error = False
428
class NoSuchRevision(BzrError):
507
429
def __init__(self, branch, revision):
508
430
self.branch = branch
509
431
self.revision = revision
432
msg = "Branch %s has no revision %s" % (branch, revision)
433
BzrError.__init__(self, msg)
512
436
class HistoryMissing(BzrError):
517
441
% (branch, object_type, object_id))
520
class DivergedBranches(BzrNewError):
521
"These branches have diverged. Use the merge command to reconcile them."""
444
class DivergedBranches(BzrError):
525
446
def __init__(self, branch1, branch2):
447
BzrError.__init__(self, "These branches have diverged. Try merge.")
526
448
self.branch1 = branch1
527
449
self.branch2 = branch2
530
class UnrelatedBranches(BzrNewError):
531
"Branches have no common ancestor, and no merge base revision was specified."
536
class NoCommonAncestor(BzrNewError):
537
"Revisions have no common ancestor: %(revision_a)s %(revision_b)s"
452
class UnrelatedBranches(BzrCommandError):
454
msg = "Branches have no common ancestor, and no base revision"\
456
BzrCommandError.__init__(self, msg)
459
class NoCommonAncestor(BzrError):
539
460
def __init__(self, revision_a, revision_b):
540
self.revision_a = revision_a
541
self.revision_b = revision_b
461
msg = "Revisions have no common ancestor: %s %s." \
462
% (revision_a, revision_b)
463
BzrError.__init__(self, msg)
544
466
class NoCommonRoot(BzrError):
569
491
def __init__(self, bases):
570
492
warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
571
493
DeprecationWarning)
572
msg = "The correct base is unclear, because %s are all equally close" %\
494
msg = "The correct base is unclear, becase %s are all equally close" %\
574
496
BzrError.__init__(self, msg)
575
497
self.bases = bases
737
659
self.format = format
740
class TransportError(BzrNewError):
741
"""Transport error: %(msg)s %(orig_error)s"""
662
class TransportError(BzrError):
663
"""All errors thrown by Transport implementations should derive
743
666
def __init__(self, msg=None, orig_error=None):
744
667
if msg is None and orig_error is not None:
745
668
msg = str(orig_error)
746
if orig_error is None:
669
BzrError.__init__(self, msg)
751
671
self.orig_error = orig_error
752
BzrNewError.__init__(self)
755
674
# A set of semi-meaningful errors which can be thrown
756
675
class TransportNotPossible(TransportError):
757
"""Transport operation not possible: %(msg)s %(orig_error)%"""
676
"""This is for transports where a specific function is explicitly not
677
possible. Such as pushing files to an HTTP server.
760
682
class ConnectionError(TransportError):
761
"""Connection error: %(msg)s %(orig_error)s"""
683
"""A connection problem prevents file retrieval.
684
This does not indicate whether the file exists or not; it indicates that a
685
precondition for requesting the file was not met.
687
def __init__(self, msg=None, orig_error=None):
688
TransportError.__init__(self, msg=msg, orig_error=orig_error)
764
691
class ConnectionReset(TransportError):
765
"""Connection closed: %(msg)s %(orig_error)s"""
768
class InvalidRange(TransportError):
769
"""Invalid range access."""
771
def __init__(self, path, offset):
772
TransportError.__init__(self, ("Invalid range access in %s at %d"
776
class InvalidHttpResponse(TransportError):
777
"""Invalid http response for %(path)s: %(msg)s"""
779
def __init__(self, path, msg, orig_error=None):
781
TransportError.__init__(self, msg, orig_error=orig_error)
784
class InvalidHttpRange(InvalidHttpResponse):
785
"""Invalid http range "%(range)s" for %(path)s: %(msg)s"""
787
def __init__(self, path, range, msg):
789
InvalidHttpResponse.__init__(self, path, msg)
792
class InvalidHttpContentType(InvalidHttpResponse):
793
"""Invalid http Content-type "%(ctype)s" for %(path)s: %(msg)s"""
795
def __init__(self, path, ctype, msg):
797
InvalidHttpResponse.__init__(self, path, msg)
692
"""The connection has been closed."""
800
696
class ConflictsInTree(BzrError):
1018
907
"""A nested progress bar was not 'finished' correctly."""
1021
class InvalidProgressBarType(BzrNewError):
1022
"""Environment variable BZR_PROGRESS_BAR='%(bar_type)s is not a supported type
1023
Select one of: %(valid_types)s"""
1025
def __init__(self, bar_type, valid_types):
1026
BzrNewError.__init__(self, bar_type=bar_type, valid_types=valid_types)
1029
910
class UnsupportedOperation(BzrNewError):
1030
911
"""The method %(mname)s is not supported on objects of type %(tname)s."""
1031
912
def __init__(self, method, method_self):
1057
938
self.measured = measured
1060
class NotABundle(BzrNewError):
1061
"""Not a bzr revision-bundle: %(text)r"""
1063
def __init__(self, text):
1064
BzrNewError.__init__(self)
1068
class BadBundle(BzrNewError):
1069
"""Bad bzr revision-bundle: %(text)r"""
1071
def __init__(self, text):
1072
BzrNewError.__init__(self)
1076
class MalformedHeader(BadBundle):
1077
"""Malformed bzr revision-bundle header: %(text)r"""
1079
def __init__(self, text):
1080
BzrNewError.__init__(self)
1084
class MalformedPatches(BadBundle):
1085
"""Malformed patches in bzr revision-bundle: %(text)r"""
1087
def __init__(self, text):
1088
BzrNewError.__init__(self)
1092
class MalformedFooter(BadBundle):
1093
"""Malformed footer in bzr revision-bundle: %(text)r"""
1095
def __init__(self, text):
1096
BzrNewError.__init__(self)
1099
class UnsupportedEOLMarker(BadBundle):
1100
"""End of line marker was not \\n in bzr revision-bundle"""
1103
BzrNewError.__init__(self)
941
class BadBundle(Exception): pass
944
class MalformedHeader(BadBundle): pass
947
class MalformedPatches(BadBundle): pass
950
class MalformedFooter(BadBundle): pass