16
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
__copyright__ = "Copyright (C) 2005 Canonical Ltd."
20
__author__ = "Martin Pool <mbp@canonical.com>"
23
######################################################################
18
# TODO: Change to a standard exception pattern:
20
# - docstring of exceptions is a template for formatting the exception
21
# so the __str__ method can be defined only in the superclass
22
# - the arguments to the exception are interpolated into this string
24
# when printing the exception we'd then require special handling only
25
# for built-in exceptions with no decent __str__ method, such as
26
# ValueError and AssertionError. See
27
# scott@canonical.com--2005/hct--devel--0.10 util/errors.py
30
"""Exceptions for bzr, and reporting of them.
32
Exceptions are caught at a high level to report errors to the user, and
33
might also be caught inside the program. Therefore it needs to be
34
possible to convert them to a meaningful string, and also for them to be
35
interrogated by the program.
37
Exceptions are defined such that the arguments given to the constructor
38
are stored in the object as properties of the same name. When the
39
object is printed as a string, the doc string of the class is used as
40
a format string with the property dictionary available to it.
42
This means that exceptions can used like this:
46
... raise NotBranchError(path='/foo/bar')
48
... print sys.exc_type
49
... print sys.exc_value
50
... print sys.exc_value.path
51
bzrlib.errors.NotBranchError
52
Not a branch: /foo/bar
57
* create a new exception class for any class of error that can be
58
usefully distinguished.
60
* the printable form of an exception is generated by the base class
64
# based on Scott James Remnant's hct error classes
25
67
class BzrError(StandardError):
69
# XXX: Should we show the exception class in
70
# exceptions that don't provide their own message?
71
# maybe it should be done at a higher level
72
## n = self.__class__.__name__ + ': '
74
if len(self.args) == 1:
75
return str(self.args[0])
76
elif len(self.args) == 2:
77
# further explanation or suggestions
79
return n + '\n '.join([self.args[0]] + self.args[1])
81
return n + "%r" % self
83
return n + `self.args`
86
class BzrNewError(Exception):
88
# base classes should override the docstring with their human-
89
# readable explanation
91
def __init__(self, **kwds):
92
for key, value in kwds.items():
93
setattr(self, key, value)
97
return self.__doc__ % self.__dict__
98
except (NameError, ValueError, KeyError), e:
99
return 'Unprintable exception %s: %s' \
100
% (self.__class__.__name__, str(e))
28
103
class BzrCheckError(BzrError):
32
107
class InvalidRevisionNumber(BzrError):
33
def __init__(self, revno):
36
108
def __str__(self):
37
109
return 'invalid revision number: %r' % self.args[0]
92
193
BzrError.__init__(self, msg)
196
class HistoryMissing(BzrError):
197
def __init__(self, branch, object_type, object_id):
199
BzrError.__init__(self,
200
'%s is missing %s {%s}'
201
% (branch, object_type, object_id))
204
class DivergedBranches(BzrError):
205
def __init__(self, branch1, branch2):
206
BzrError.__init__(self, "These branches have diverged.")
207
self.branch1 = branch1
208
self.branch2 = branch2
211
class UnrelatedBranches(BzrCommandError):
213
msg = "Branches have no common ancestor, and no base revision"\
215
BzrCommandError.__init__(self, msg)
217
class NoCommonAncestor(BzrError):
218
def __init__(self, revision_a, revision_b):
219
msg = "Revisions have no common ancestor: %s %s." \
220
% (revision_a, revision_b)
221
BzrError.__init__(self, msg)
223
class NoCommonRoot(BzrError):
224
def __init__(self, revision_a, revision_b):
225
msg = "Revisions are not derived from the same root: %s %s." \
226
% (revision_a, revision_b)
227
BzrError.__init__(self, msg)
229
class NotAncestor(BzrError):
230
def __init__(self, rev_id, not_ancestor_id):
231
msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id,
233
BzrError.__init__(self, msg)
235
self.not_ancestor_id = not_ancestor_id
238
class NotAncestor(BzrError):
239
def __init__(self, rev_id, not_ancestor_id):
241
self.not_ancestor_id = not_ancestor_id
242
msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id,
244
BzrError.__init__(self, msg)
247
class InstallFailed(BzrError):
248
def __init__(self, revisions):
249
msg = "Could not install revisions:\n%s" % " ,".join(revisions)
250
BzrError.__init__(self, msg)
251
self.revisions = revisions
254
class AmbiguousBase(BzrError):
255
def __init__(self, bases):
256
msg = "The correct base is unclear, becase %s are all equally close" %\
258
BzrError.__init__(self, msg)
261
class NoCommits(BzrError):
262
def __init__(self, branch):
263
msg = "Branch %s has no commits." % branch
264
BzrError.__init__(self, msg)
266
class UnlistableStore(BzrError):
267
def __init__(self, store):
268
BzrError.__init__(self, "Store %s is not listable" % store)
270
class UnlistableBranch(BzrError):
271
def __init__(self, br):
272
BzrError.__init__(self, "Stores for branch %s are not listable" % br)
275
from bzrlib.weave import WeaveError, WeaveParentMismatch
277
class TransportError(BzrError):
278
"""All errors thrown by Transport implementations should derive
281
def __init__(self, msg=None, orig_error=None):
282
if msg is None and orig_error is not None:
283
msg = str(orig_error)
284
BzrError.__init__(self, msg)
286
self.orig_error = orig_error
288
# A set of semi-meaningful errors which can be thrown
289
class TransportNotPossible(TransportError):
290
"""This is for transports where a specific function is explicitly not
291
possible. Such as pushing files to an HTTP server.
295
class NonRelativePath(TransportError):
296
"""An absolute path was supplied, that could not be decoded into
301
class NoSuchFile(TransportError, IOError):
302
"""A get() was issued for a file that doesn't exist."""
304
# XXX: Is multiple inheritance for exceptions really needed?
307
return 'no such file: ' + self.msg
309
def __init__(self, msg=None, orig_error=None):
311
TransportError.__init__(self, msg=msg, orig_error=orig_error)
312
IOError.__init__(self, errno.ENOENT, self.msg)
314
class FileExists(TransportError, OSError):
315
"""An operation was attempted, which would overwrite an entry,
316
but overwritting is not supported.
318
mkdir() can throw this, but put() just overwites existing files.
320
# XXX: Is multiple inheritance for exceptions really needed?
321
def __init__(self, msg=None, orig_error=None):
323
TransportError.__init__(self, msg=msg, orig_error=orig_error)
324
OSError.__init__(self, errno.EEXIST, self.msg)
326
class PermissionDenied(TransportError):
327
"""An operation cannot succeed because of a lack of permissions."""
330
class ConnectionReset(TransportError):
331
"""The connection has been closed."""
334
class ConflictsInTree(BzrError):
336
BzrError.__init__(self, "Working tree has conflicts.")