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.
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
46
58
* 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
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
56
69
from warnings import warn
166
class BzrCommandError(BzrError):
167
# Error from malformed user command
168
# This is being misused as a generic exception
169
# pleae subclass. RBC 20051030
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.
171
195
# I think it's a waste of effort to differentiate between errors that
172
196
# are not intended to be caught anyway. UI code need not subclass
173
197
# BzrCommandError, and non-UI code should not throw a subclass of
174
198
# BzrCommandError. ADHB 20051211
199
def __init__(self, msg):
175
202
def __str__(self):
179
206
class BzrOptionError(BzrCommandError):
180
"""Some missing or otherwise incorrect option was supplied."""
207
"""Error in command line options"""
183
class StrictCommitFailed(Exception):
184
"""Commit refused because there are unknowns in the tree."""
210
class StrictCommitFailed(BzrNewError):
211
"""Commit refused because there are unknown files in the tree"""
187
214
# XXX: Should be unified with TransportError; they seem to represent the
231
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)
234
268
class PathNotChild(BzrNewError):
235
269
"""Path %(path)r is not a child of path %(base)r%(extra)s"""
271
is_user_error = False
236
273
def __init__(self, path, base, extra=None):
237
274
BzrNewError.__init__(self)
283
class UnsupportedFormatError(BzrError):
284
"""Specified path is a bzr branch that we recognize but cannot read."""
286
return 'unsupported branch format: %s' % self.args[0]
289
class UnknownFormatError(BzrError):
290
"""Specified path is a bzr branch whose format we do not recognize."""
292
return 'unknown branch format: %s' % self.args[0]
324
class UnsupportedFormatError(BzrNewError):
325
"""Unsupported branch format: %(format)s"""
328
class UnknownFormatError(BzrNewError):
329
"""Unknown branch format: %(format)r"""
295
332
class IncompatibleFormat(BzrNewError):
333
370
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
336
class BadFileKindError(BzrError):
337
"""Specified file is of a kind that cannot be added.
339
(For example a symlink or device file.)"""
342
class ForbiddenFileError(BzrError):
343
"""Cannot operate on a file because it is a control file."""
373
class BadFileKindError(BzrNewError):
374
"""Cannot operate on %(filename)s of unsupported kind %(kind)s"""
377
class ForbiddenControlFileError(BzrNewError):
378
"""Cannot operate on %(filename)s because it is a control file"""
346
381
class LockError(BzrNewError):
445
483
"""Commit refused because there are unknowns in the tree."""
448
class NoSuchRevision(BzrError):
486
class NoSuchRevision(BzrNewError):
487
"""Branch %(branch)s has no revision %(revision)s"""
489
is_user_error = False
449
491
def __init__(self, branch, revision):
450
492
self.branch = branch
451
493
self.revision = revision
452
msg = "Branch %s has no revision %s" % (branch, revision)
453
BzrError.__init__(self, msg)
456
496
class HistoryMissing(BzrError):
461
501
% (branch, object_type, object_id))
464
class DivergedBranches(BzrError):
504
class DivergedBranches(BzrNewError):
505
"These branches have diverged. Use the merge command to reconcile them."""
466
509
def __init__(self, branch1, branch2):
467
BzrError.__init__(self, "These branches have diverged. Try merge.")
468
510
self.branch1 = branch1
469
511
self.branch2 = branch2
472
class UnrelatedBranches(BzrCommandError):
474
msg = "Branches have no common ancestor, and no base revision"\
476
BzrCommandError.__init__(self, msg)
479
class NoCommonAncestor(BzrError):
514
class UnrelatedBranches(BzrNewError):
515
"Branches have no common ancestor, and no merge base revision was specified."
520
class NoCommonAncestor(BzrNewError):
521
"Revisions have no common ancestor: %(revision_a)s %(revision_b)s"
480
523
def __init__(self, revision_a, revision_b):
481
msg = "Revisions have no common ancestor: %s %s." \
482
% (revision_a, revision_b)
483
BzrError.__init__(self, msg)
524
self.revision_a = revision_a
525
self.revision_b = revision_b
486
528
class NoCommonRoot(BzrError):
511
553
def __init__(self, bases):
512
554
warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
513
555
DeprecationWarning)
514
msg = "The correct base is unclear, becase %s are all equally close" %\
556
msg = "The correct base is unclear, because %s are all equally close" %\
516
558
BzrError.__init__(self, msg)
517
559
self.bases = bases
679
721
self.format = format
682
class TransportError(BzrError):
683
"""All errors thrown by Transport implementations should derive
724
class TransportError(BzrNewError):
725
"""Transport error: %(msg)s %(orig_error)s"""
686
727
def __init__(self, msg=None, orig_error=None):
687
728
if msg is None and orig_error is not None:
688
729
msg = str(orig_error)
689
BzrError.__init__(self, msg)
730
if orig_error is None:
691
735
self.orig_error = orig_error
736
BzrNewError.__init__(self)
694
739
# A set of semi-meaningful errors which can be thrown
695
740
class TransportNotPossible(TransportError):
696
"""This is for transports where a specific function is explicitly not
697
possible. Such as pushing files to an HTTP server.
741
"""Transport operation not possible: %(msg)s %(orig_error)%"""
702
744
class ConnectionError(TransportError):
703
"""A connection problem prevents file retrieval.
704
This does not indicate whether the file exists or not; it indicates that a
705
precondition for requesting the file was not met.
707
def __init__(self, msg=None, orig_error=None):
708
TransportError.__init__(self, msg=msg, orig_error=orig_error)
745
"""Connection error: %(msg)s %(orig_error)s"""
711
748
class ConnectionReset(TransportError):
712
"""The connection has been closed."""
749
"""Connection closed: %(msg)s %(orig_error)s"""
752
class InvalidRange(TransportError):
753
"""Invalid range access."""
755
def __init__(self, path, offset):
756
TransportError.__init__(self, ("Invalid range access in %s at %d"
760
class InvalidHttpResponse(TransportError):
761
"""Invalid http response for %(path)s: %(msg)s"""
763
def __init__(self, path, msg, orig_error=None):
765
TransportError.__init__(self, msg, orig_error=orig_error)
768
class InvalidHttpRange(InvalidHttpResponse):
769
"""Invalid http range "%(range)s" for %(path)s: %(msg)s"""
771
def __init__(self, path, range, msg):
773
InvalidHttpResponse.__init__(self, path, msg)
776
class InvalidHttpContentType(InvalidHttpResponse):
777
"""Invalid http Content-type "%(ctype)s" for %(path)s: %(msg)s"""
779
def __init__(self, path, ctype, msg):
781
InvalidHttpResponse.__init__(self, path, msg)
716
784
class ConflictsInTree(BzrError):
927
1002
"""A nested progress bar was not 'finished' correctly."""
1005
class InvalidProgressBarType(BzrNewError):
1006
"""Environment variable BZR_PROGRESS_BAR='%(bar_type)s is not a supported type
1007
Select one of: %(valid_types)s"""
1009
def __init__(self, bar_type, valid_types):
1010
BzrNewError.__init__(self, bar_type=bar_type, valid_types=valid_types)
930
1013
class UnsupportedOperation(BzrNewError):
931
1014
"""The method %(mname)s is not supported on objects of type %(tname)s."""
932
1015
def __init__(self, method, method_self):