15
14
# along with this program; if not, write to the Free Software
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
######################################################################
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
... print sys.exc_value.path
38
bzrlib.errors.NotBranchError
39
Not a branch: /foo/bar
44
* create a new exception class for any class of error that can be
45
usefully distinguished.
47
* the printable form of an exception is generated by the base class
51
# based on Scott James Remnant's hct error classes
53
# TODO: is there any value in providing the .args field used by standard
54
# python exceptions? A list of values with no names seems less useful
57
# TODO: Perhaps convert the exception to a string at the moment it's
58
# constructed to make sure it will succeed. But that says nothing about
59
# exceptions that are never raised.
61
# TODO: Convert all the other error classes here to BzrNewError, and eliminate
25
65
class BzrError(StandardError):
28
class BzrCheckError(BzrError):
67
# XXX: Should we show the exception class in
68
# exceptions that don't provide their own message?
69
# maybe it should be done at a higher level
70
## n = self.__class__.__name__ + ': '
72
if len(self.args) == 1:
73
return str(self.args[0])
74
elif len(self.args) == 2:
75
# further explanation or suggestions
77
return n + '\n '.join([self.args[0]] + self.args[1])
79
return n + "%r" % self
81
return n + `self.args`
84
class BzrNewError(BzrError):
86
# base classes should override the docstring with their human-
87
# readable explanation
89
def __init__(self, **kwds):
90
for key, value in kwds.items():
91
setattr(self, key, value)
95
return self.__doc__ % self.__dict__
96
except (NameError, ValueError, KeyError), e:
97
return 'Unprintable exception %s: %s' \
98
% (self.__class__.__name__, str(e))
101
class BzrCheckError(BzrNewError):
102
"""Internal check failed: %(message)s"""
103
def __init__(self, message):
104
BzrNewError.__init__(self)
105
self.message = message
108
class InvalidEntryName(BzrNewError):
109
"""Invalid entry name: %(name)s"""
110
def __init__(self, name):
111
BzrNewError.__init__(self)
115
class InvalidRevisionNumber(BzrNewError):
116
"""Invalid revision number %(revno)d"""
117
def __init__(self, revno):
118
BzrNewError.__init__(self)
122
class InvalidRevisionId(BzrNewError):
123
"""Invalid revision-id {%(revision_id)s} in %(branch)s"""
124
def __init__(self, revision_id, branch):
125
BzrNewError.__init__(self)
126
self.revision_id = revision_id
32
130
class BzrCommandError(BzrError):
33
131
# Error from malformed user command
37
def bailout(msg, explanation=[]):
38
ex = BzrError(msg, explanation)
40
trace._tracefile.write('* raising %s\n' % ex)
132
# This is being misused as a generic exception
133
# pleae subclass. RBC 20051030
138
class BzrOptionError(BzrCommandError):
139
"""Some missing or otherwise incorrect option was supplied."""
142
class StrictCommitFailed(Exception):
143
"""Commit refused because there are unknowns in the tree."""
145
class NotBranchError(BzrNewError):
146
"""Not a branch: %(path)s"""
147
def __init__(self, path):
148
BzrNewError.__init__(self)
152
class UnsupportedFormatError(BzrError):
153
"""Specified path is a bzr branch that we cannot read."""
155
return 'unsupported branch format: %s' % self.args[0]
158
class NotVersionedError(BzrNewError):
159
"""%(path)s is not versioned"""
160
def __init__(self, path):
161
BzrNewError.__init__(self)
165
class BadFileKindError(BzrError):
166
"""Specified file is of a kind that cannot be added.
168
(For example a symlink or device file.)"""
171
class ForbiddenFileError(BzrError):
172
"""Cannot operate on a file because it is a control file."""
175
class LockError(Exception):
177
# All exceptions from the lock/unlock functions should be from
178
# this exception class. They will be translated as necessary. The
179
# original exception is available as e.original_error
182
class CommitNotPossible(LockError):
183
"""A commit was attempted but we do not have a write lock open."""
186
class AlreadyCommitted(LockError):
187
"""A rollback was requested, but is not able to be accomplished."""
190
class ReadOnlyError(LockError):
191
"""A write attempt was made in a read only transaction."""
194
class PointlessCommit(BzrNewError):
195
"""No changes to commit"""
197
class StrictCommitFailed(Exception):
198
"""Commit refused because there are unknowns in the tree."""
200
class NoSuchRevision(BzrError):
201
def __init__(self, branch, revision):
203
self.revision = revision
204
msg = "Branch %s has no revision %s" % (branch, revision)
205
BzrError.__init__(self, msg)
208
class HistoryMissing(BzrError):
209
def __init__(self, branch, object_type, object_id):
211
BzrError.__init__(self,
212
'%s is missing %s {%s}'
213
% (branch, object_type, object_id))
216
class DivergedBranches(BzrError):
217
def __init__(self, branch1, branch2):
218
BzrError.__init__(self, "These branches have diverged.")
219
self.branch1 = branch1
220
self.branch2 = branch2
223
class UnrelatedBranches(BzrCommandError):
225
msg = "Branches have no common ancestor, and no base revision"\
227
BzrCommandError.__init__(self, msg)
229
class NoCommonAncestor(BzrError):
230
def __init__(self, revision_a, revision_b):
231
msg = "Revisions have no common ancestor: %s %s." \
232
% (revision_a, revision_b)
233
BzrError.__init__(self, msg)
235
class NoCommonRoot(BzrError):
236
def __init__(self, revision_a, revision_b):
237
msg = "Revisions are not derived from the same root: %s %s." \
238
% (revision_a, revision_b)
239
BzrError.__init__(self, msg)
241
class NotAncestor(BzrError):
242
def __init__(self, rev_id, not_ancestor_id):
243
msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id,
245
BzrError.__init__(self, msg)
247
self.not_ancestor_id = not_ancestor_id
250
class NotAncestor(BzrError):
251
def __init__(self, rev_id, not_ancestor_id):
253
self.not_ancestor_id = not_ancestor_id
254
msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id,
256
BzrError.__init__(self, msg)
259
class InstallFailed(BzrError):
260
def __init__(self, revisions):
261
msg = "Could not install revisions:\n%s" % " ,".join(revisions)
262
BzrError.__init__(self, msg)
263
self.revisions = revisions
266
class AmbiguousBase(BzrError):
267
def __init__(self, bases):
268
msg = "The correct base is unclear, becase %s are all equally close" %\
270
BzrError.__init__(self, msg)
273
class NoCommits(BzrError):
274
def __init__(self, branch):
275
msg = "Branch %s has no commits." % branch
276
BzrError.__init__(self, msg)
278
class UnlistableStore(BzrError):
279
def __init__(self, store):
280
BzrError.__init__(self, "Store %s is not listable" % store)
282
class UnlistableBranch(BzrError):
283
def __init__(self, br):
284
BzrError.__init__(self, "Stores for branch %s are not listable" % br)
287
class WeaveError(BzrNewError):
288
"""Error in processing weave: %(message)s"""
289
def __init__(self, message=None):
290
BzrNewError.__init__(self)
291
self.message = message
294
class WeaveRevisionAlreadyPresent(WeaveError):
295
"""Revision {%(revision_id)s} already present in %(weave)s"""
296
def __init__(self, revision_id, weave):
297
WeaveError.__init__(self)
298
self.revision_id = revision_id
302
class WeaveRevisionNotPresent(WeaveError):
303
"""Revision {%(revision_id)s} not present in %(weave)s"""
304
def __init__(self, revision_id, weave):
305
WeaveError.__init__(self)
306
self.revision_id = revision_id
310
class WeaveFormatError(WeaveError):
311
"""Weave invariant violated: %(what)s"""
312
def __init__(self, what):
313
WeaveError.__init__(self)
317
class WeaveParentMismatch(WeaveError):
318
"""Parents are mismatched between two revisions."""
321
class TransportError(BzrError):
322
"""All errors thrown by Transport implementations should derive
325
def __init__(self, msg=None, orig_error=None):
326
if msg is None and orig_error is not None:
327
msg = str(orig_error)
328
BzrError.__init__(self, msg)
330
self.orig_error = orig_error
332
# A set of semi-meaningful errors which can be thrown
333
class TransportNotPossible(TransportError):
334
"""This is for transports where a specific function is explicitly not
335
possible. Such as pushing files to an HTTP server.
339
class NonRelativePath(TransportError):
340
"""An absolute path was supplied, that could not be decoded into
345
class NoSuchFile(TransportError, IOError):
346
"""A get() was issued for a file that doesn't exist."""
348
# XXX: Is multiple inheritance for exceptions really needed?
351
return 'no such file: ' + self.msg
353
def __init__(self, msg=None, orig_error=None):
355
TransportError.__init__(self, msg=msg, orig_error=orig_error)
356
IOError.__init__(self, errno.ENOENT, self.msg)
358
class FileExists(TransportError, OSError):
359
"""An operation was attempted, which would overwrite an entry,
360
but overwritting is not supported.
362
mkdir() can throw this, but put() just overwites existing files.
364
# XXX: Is multiple inheritance for exceptions really needed?
365
def __init__(self, msg=None, orig_error=None):
367
TransportError.__init__(self, msg=msg, orig_error=orig_error)
368
OSError.__init__(self, errno.EEXIST, self.msg)
370
class PermissionDenied(TransportError):
371
"""An operation cannot succeed because of a lack of permissions."""
374
class ConnectionReset(TransportError):
375
"""The connection has been closed."""
378
class ConflictsInTree(BzrError):
380
BzrError.__init__(self, "Working tree has conflicts.")
382
class ParseConfigError(BzrError):
383
def __init__(self, errors, filename):
386
message = "Error(s) parsing config file %s:\n%s" % \
387
(filename, ('\n'.join(e.message for e in errors)))
388
BzrError.__init__(self, message)
390
class SigningFailed(BzrError):
391
def __init__(self, command_line):
392
BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
395
class WorkingTreeNotRevision(BzrError):
396
def __init__(self, tree):
397
BzrError.__init__(self, "The working tree for %s has changed since"
398
" last commit, but weave merge requires that it be"
399
" unchanged." % tree.basedir)
401
class CantReprocessAndShowBase(BzrNewError):
402
"""Can't reprocess and show base.
403
Reprocessing obscures relationship of conflicting lines to base."""
405
class GraphCycleError(BzrNewError):
406
"""Cycle in graph %(graph)r"""
407
def __init__(self, graph):
408
BzrNewError.__init__(self)
411
class MustUseDecorated(Exception):
412
"""A decorating function has requested its original command be used.
414
This should never escape bzr, so does not need to be printable.