##// END OF EJS Templates
py3: unimplement RevlogError.__str__()...
Yuya Nishihara -
r41008:2393c404 default
parent child Browse files
Show More
@@ -1,344 +1,336
1 # error.py - Mercurial exceptions
1 # error.py - Mercurial exceptions
2 #
2 #
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """Mercurial exceptions.
8 """Mercurial exceptions.
9
9
10 This allows us to catch exceptions at higher levels without forcing
10 This allows us to catch exceptions at higher levels without forcing
11 imports.
11 imports.
12 """
12 """
13
13
14 from __future__ import absolute_import
14 from __future__ import absolute_import
15
15
16 # Do not import anything but pycompat here, please
16 # Do not import anything but pycompat here, please
17 from . import pycompat
17 from . import pycompat
18
18
19 def _tobytes(exc):
19 def _tobytes(exc):
20 """Byte-stringify exception in the same way as BaseException_str()"""
20 """Byte-stringify exception in the same way as BaseException_str()"""
21 if not exc.args:
21 if not exc.args:
22 return b''
22 return b''
23 if len(exc.args) == 1:
23 if len(exc.args) == 1:
24 return pycompat.bytestr(exc.args[0])
24 return pycompat.bytestr(exc.args[0])
25 return b'(%s)' % b', '.join(b"'%s'" % pycompat.bytestr(a) for a in exc.args)
25 return b'(%s)' % b', '.join(b"'%s'" % pycompat.bytestr(a) for a in exc.args)
26
26
27 class Hint(object):
27 class Hint(object):
28 """Mix-in to provide a hint of an error
28 """Mix-in to provide a hint of an error
29
29
30 This should come first in the inheritance list to consume a hint and
30 This should come first in the inheritance list to consume a hint and
31 pass remaining arguments to the exception class.
31 pass remaining arguments to the exception class.
32 """
32 """
33 def __init__(self, *args, **kw):
33 def __init__(self, *args, **kw):
34 self.hint = kw.pop(r'hint', None)
34 self.hint = kw.pop(r'hint', None)
35 super(Hint, self).__init__(*args, **kw)
35 super(Hint, self).__init__(*args, **kw)
36
36
37 class StorageError(Hint, Exception):
37 class StorageError(Hint, Exception):
38 """Raised when an error occurs in a storage layer.
38 """Raised when an error occurs in a storage layer.
39
39
40 Usually subclassed by a storage-specific exception.
40 Usually subclassed by a storage-specific exception.
41 """
41 """
42 __bytes__ = _tobytes
42 __bytes__ = _tobytes
43
43
44 class RevlogError(StorageError):
44 class RevlogError(StorageError):
45 __bytes__ = _tobytes
45 __bytes__ = _tobytes
46
46
47 def __str__(self):
48 # avoid cycle, and directly implement unimethod for this
49 # __str__ to allow delaying the import of encoding until
50 # someone actually wants the __str__ of a RevlogError (which
51 # should be very rare).
52 from . import encoding
53 return encoding.unifromlocal(_tobytes(self))
54
55 class FilteredIndexError(IndexError):
47 class FilteredIndexError(IndexError):
56 __bytes__ = _tobytes
48 __bytes__ = _tobytes
57
49
58 class LookupError(RevlogError, KeyError):
50 class LookupError(RevlogError, KeyError):
59 def __init__(self, name, index, message):
51 def __init__(self, name, index, message):
60 self.name = name
52 self.name = name
61 self.index = index
53 self.index = index
62 # this can't be called 'message' because at least some installs of
54 # this can't be called 'message' because at least some installs of
63 # Python 2.6+ complain about the 'message' property being deprecated
55 # Python 2.6+ complain about the 'message' property being deprecated
64 self.lookupmessage = message
56 self.lookupmessage = message
65 if isinstance(name, bytes) and len(name) == 20:
57 if isinstance(name, bytes) and len(name) == 20:
66 from .node import short
58 from .node import short
67 name = short(name)
59 name = short(name)
68 RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
60 RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
69
61
70 def __bytes__(self):
62 def __bytes__(self):
71 return RevlogError.__bytes__(self)
63 return RevlogError.__bytes__(self)
72
64
73 def __str__(self):
65 def __str__(self):
74 return RevlogError.__str__(self)
66 return RevlogError.__str__(self)
75
67
76 class AmbiguousPrefixLookupError(LookupError):
68 class AmbiguousPrefixLookupError(LookupError):
77 pass
69 pass
78
70
79 class FilteredLookupError(LookupError):
71 class FilteredLookupError(LookupError):
80 pass
72 pass
81
73
82 class ManifestLookupError(LookupError):
74 class ManifestLookupError(LookupError):
83 pass
75 pass
84
76
85 class CommandError(Exception):
77 class CommandError(Exception):
86 """Exception raised on errors in parsing the command line."""
78 """Exception raised on errors in parsing the command line."""
87 __bytes__ = _tobytes
79 __bytes__ = _tobytes
88
80
89 class InterventionRequired(Hint, Exception):
81 class InterventionRequired(Hint, Exception):
90 """Exception raised when a command requires human intervention."""
82 """Exception raised when a command requires human intervention."""
91 __bytes__ = _tobytes
83 __bytes__ = _tobytes
92
84
93 class Abort(Hint, Exception):
85 class Abort(Hint, Exception):
94 """Raised if a command needs to print an error and exit."""
86 """Raised if a command needs to print an error and exit."""
95 __bytes__ = _tobytes
87 __bytes__ = _tobytes
96
88
97 class HookLoadError(Abort):
89 class HookLoadError(Abort):
98 """raised when loading a hook fails, aborting an operation
90 """raised when loading a hook fails, aborting an operation
99
91
100 Exists to allow more specialized catching."""
92 Exists to allow more specialized catching."""
101
93
102 class HookAbort(Abort):
94 class HookAbort(Abort):
103 """raised when a validation hook fails, aborting an operation
95 """raised when a validation hook fails, aborting an operation
104
96
105 Exists to allow more specialized catching."""
97 Exists to allow more specialized catching."""
106
98
107 class ConfigError(Abort):
99 class ConfigError(Abort):
108 """Exception raised when parsing config files"""
100 """Exception raised when parsing config files"""
109
101
110 class UpdateAbort(Abort):
102 class UpdateAbort(Abort):
111 """Raised when an update is aborted for destination issue"""
103 """Raised when an update is aborted for destination issue"""
112
104
113 class MergeDestAbort(Abort):
105 class MergeDestAbort(Abort):
114 """Raised when an update is aborted for destination issues"""
106 """Raised when an update is aborted for destination issues"""
115
107
116 class NoMergeDestAbort(MergeDestAbort):
108 class NoMergeDestAbort(MergeDestAbort):
117 """Raised when an update is aborted because there is nothing to merge"""
109 """Raised when an update is aborted because there is nothing to merge"""
118
110
119 class ManyMergeDestAbort(MergeDestAbort):
111 class ManyMergeDestAbort(MergeDestAbort):
120 """Raised when an update is aborted because destination is ambiguous"""
112 """Raised when an update is aborted because destination is ambiguous"""
121
113
122 class ResponseExpected(Abort):
114 class ResponseExpected(Abort):
123 """Raised when an EOF is received for a prompt"""
115 """Raised when an EOF is received for a prompt"""
124 def __init__(self):
116 def __init__(self):
125 from .i18n import _
117 from .i18n import _
126 Abort.__init__(self, _('response expected'))
118 Abort.__init__(self, _('response expected'))
127
119
128 class OutOfBandError(Hint, Exception):
120 class OutOfBandError(Hint, Exception):
129 """Exception raised when a remote repo reports failure"""
121 """Exception raised when a remote repo reports failure"""
130 __bytes__ = _tobytes
122 __bytes__ = _tobytes
131
123
132 class ParseError(Hint, Exception):
124 class ParseError(Hint, Exception):
133 """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
125 """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
134 __bytes__ = _tobytes
126 __bytes__ = _tobytes
135
127
136 class PatchError(Exception):
128 class PatchError(Exception):
137 __bytes__ = _tobytes
129 __bytes__ = _tobytes
138
130
139 class UnknownIdentifier(ParseError):
131 class UnknownIdentifier(ParseError):
140 """Exception raised when a {rev,file}set references an unknown identifier"""
132 """Exception raised when a {rev,file}set references an unknown identifier"""
141
133
142 def __init__(self, function, symbols):
134 def __init__(self, function, symbols):
143 from .i18n import _
135 from .i18n import _
144 ParseError.__init__(self, _("unknown identifier: %s") % function)
136 ParseError.__init__(self, _("unknown identifier: %s") % function)
145 self.function = function
137 self.function = function
146 self.symbols = symbols
138 self.symbols = symbols
147
139
148 class RepoError(Hint, Exception):
140 class RepoError(Hint, Exception):
149 __bytes__ = _tobytes
141 __bytes__ = _tobytes
150
142
151 class RepoLookupError(RepoError):
143 class RepoLookupError(RepoError):
152 pass
144 pass
153
145
154 class FilteredRepoLookupError(RepoLookupError):
146 class FilteredRepoLookupError(RepoLookupError):
155 pass
147 pass
156
148
157 class CapabilityError(RepoError):
149 class CapabilityError(RepoError):
158 pass
150 pass
159
151
160 class RequirementError(RepoError):
152 class RequirementError(RepoError):
161 """Exception raised if .hg/requires has an unknown entry."""
153 """Exception raised if .hg/requires has an unknown entry."""
162
154
163 class StdioError(IOError):
155 class StdioError(IOError):
164 """Raised if I/O to stdout or stderr fails"""
156 """Raised if I/O to stdout or stderr fails"""
165
157
166 def __init__(self, err):
158 def __init__(self, err):
167 IOError.__init__(self, err.errno, err.strerror)
159 IOError.__init__(self, err.errno, err.strerror)
168
160
169 # no __bytes__() because error message is derived from the standard IOError
161 # no __bytes__() because error message is derived from the standard IOError
170
162
171 class UnsupportedMergeRecords(Abort):
163 class UnsupportedMergeRecords(Abort):
172 def __init__(self, recordtypes):
164 def __init__(self, recordtypes):
173 from .i18n import _
165 from .i18n import _
174 self.recordtypes = sorted(recordtypes)
166 self.recordtypes = sorted(recordtypes)
175 s = ' '.join(self.recordtypes)
167 s = ' '.join(self.recordtypes)
176 Abort.__init__(
168 Abort.__init__(
177 self, _('unsupported merge state records: %s') % s,
169 self, _('unsupported merge state records: %s') % s,
178 hint=_('see https://mercurial-scm.org/wiki/MergeStateRecords for '
170 hint=_('see https://mercurial-scm.org/wiki/MergeStateRecords for '
179 'more information'))
171 'more information'))
180
172
181 class UnknownVersion(Abort):
173 class UnknownVersion(Abort):
182 """generic exception for aborting from an encounter with an unknown version
174 """generic exception for aborting from an encounter with an unknown version
183 """
175 """
184
176
185 def __init__(self, msg, hint=None, version=None):
177 def __init__(self, msg, hint=None, version=None):
186 self.version = version
178 self.version = version
187 super(UnknownVersion, self).__init__(msg, hint=hint)
179 super(UnknownVersion, self).__init__(msg, hint=hint)
188
180
189 class LockError(IOError):
181 class LockError(IOError):
190 def __init__(self, errno, strerror, filename, desc):
182 def __init__(self, errno, strerror, filename, desc):
191 IOError.__init__(self, errno, strerror, filename)
183 IOError.__init__(self, errno, strerror, filename)
192 self.desc = desc
184 self.desc = desc
193
185
194 # no __bytes__() because error message is derived from the standard IOError
186 # no __bytes__() because error message is derived from the standard IOError
195
187
196 class LockHeld(LockError):
188 class LockHeld(LockError):
197 def __init__(self, errno, filename, desc, locker):
189 def __init__(self, errno, filename, desc, locker):
198 LockError.__init__(self, errno, 'Lock held', filename, desc)
190 LockError.__init__(self, errno, 'Lock held', filename, desc)
199 self.locker = locker
191 self.locker = locker
200
192
201 class LockUnavailable(LockError):
193 class LockUnavailable(LockError):
202 pass
194 pass
203
195
204 # LockError is for errors while acquiring the lock -- this is unrelated
196 # LockError is for errors while acquiring the lock -- this is unrelated
205 class LockInheritanceContractViolation(RuntimeError):
197 class LockInheritanceContractViolation(RuntimeError):
206 __bytes__ = _tobytes
198 __bytes__ = _tobytes
207
199
208 class ResponseError(Exception):
200 class ResponseError(Exception):
209 """Raised to print an error with part of output and exit."""
201 """Raised to print an error with part of output and exit."""
210 __bytes__ = _tobytes
202 __bytes__ = _tobytes
211
203
212 class UnknownCommand(Exception):
204 class UnknownCommand(Exception):
213 """Exception raised if command is not in the command table."""
205 """Exception raised if command is not in the command table."""
214 __bytes__ = _tobytes
206 __bytes__ = _tobytes
215
207
216 class AmbiguousCommand(Exception):
208 class AmbiguousCommand(Exception):
217 """Exception raised if command shortcut matches more than one command."""
209 """Exception raised if command shortcut matches more than one command."""
218 __bytes__ = _tobytes
210 __bytes__ = _tobytes
219
211
220 # derived from KeyboardInterrupt to simplify some breakout code
212 # derived from KeyboardInterrupt to simplify some breakout code
221 class SignalInterrupt(KeyboardInterrupt):
213 class SignalInterrupt(KeyboardInterrupt):
222 """Exception raised on SIGTERM and SIGHUP."""
214 """Exception raised on SIGTERM and SIGHUP."""
223
215
224 class SignatureError(Exception):
216 class SignatureError(Exception):
225 __bytes__ = _tobytes
217 __bytes__ = _tobytes
226
218
227 class PushRaced(RuntimeError):
219 class PushRaced(RuntimeError):
228 """An exception raised during unbundling that indicate a push race"""
220 """An exception raised during unbundling that indicate a push race"""
229 __bytes__ = _tobytes
221 __bytes__ = _tobytes
230
222
231 class ProgrammingError(Hint, RuntimeError):
223 class ProgrammingError(Hint, RuntimeError):
232 """Raised if a mercurial (core or extension) developer made a mistake"""
224 """Raised if a mercurial (core or extension) developer made a mistake"""
233
225
234 def __init__(self, msg, *args, **kwargs):
226 def __init__(self, msg, *args, **kwargs):
235 # On Python 3, turn the message back into a string since this is
227 # On Python 3, turn the message back into a string since this is
236 # an internal-only error that won't be printed except in a
228 # an internal-only error that won't be printed except in a
237 # stack traces.
229 # stack traces.
238 msg = pycompat.sysstr(msg)
230 msg = pycompat.sysstr(msg)
239 super(ProgrammingError, self).__init__(msg, *args, **kwargs)
231 super(ProgrammingError, self).__init__(msg, *args, **kwargs)
240
232
241 __bytes__ = _tobytes
233 __bytes__ = _tobytes
242
234
243 class WdirUnsupported(Exception):
235 class WdirUnsupported(Exception):
244 """An exception which is raised when 'wdir()' is not supported"""
236 """An exception which is raised when 'wdir()' is not supported"""
245 __bytes__ = _tobytes
237 __bytes__ = _tobytes
246
238
247 # bundle2 related errors
239 # bundle2 related errors
248 class BundleValueError(ValueError):
240 class BundleValueError(ValueError):
249 """error raised when bundle2 cannot be processed"""
241 """error raised when bundle2 cannot be processed"""
250 __bytes__ = _tobytes
242 __bytes__ = _tobytes
251
243
252 class BundleUnknownFeatureError(BundleValueError):
244 class BundleUnknownFeatureError(BundleValueError):
253 def __init__(self, parttype=None, params=(), values=()):
245 def __init__(self, parttype=None, params=(), values=()):
254 self.parttype = parttype
246 self.parttype = parttype
255 self.params = params
247 self.params = params
256 self.values = values
248 self.values = values
257 if self.parttype is None:
249 if self.parttype is None:
258 msg = 'Stream Parameter'
250 msg = 'Stream Parameter'
259 else:
251 else:
260 msg = parttype
252 msg = parttype
261 entries = self.params
253 entries = self.params
262 if self.params and self.values:
254 if self.params and self.values:
263 assert len(self.params) == len(self.values)
255 assert len(self.params) == len(self.values)
264 entries = []
256 entries = []
265 for idx, par in enumerate(self.params):
257 for idx, par in enumerate(self.params):
266 val = self.values[idx]
258 val = self.values[idx]
267 if val is None:
259 if val is None:
268 entries.append(val)
260 entries.append(val)
269 else:
261 else:
270 entries.append("%s=%r" % (par, pycompat.maybebytestr(val)))
262 entries.append("%s=%r" % (par, pycompat.maybebytestr(val)))
271 if entries:
263 if entries:
272 msg = '%s - %s' % (msg, ', '.join(entries))
264 msg = '%s - %s' % (msg, ', '.join(entries))
273 ValueError.__init__(self, msg)
265 ValueError.__init__(self, msg)
274
266
275 class ReadOnlyPartError(RuntimeError):
267 class ReadOnlyPartError(RuntimeError):
276 """error raised when code tries to alter a part being generated"""
268 """error raised when code tries to alter a part being generated"""
277 __bytes__ = _tobytes
269 __bytes__ = _tobytes
278
270
279 class PushkeyFailed(Abort):
271 class PushkeyFailed(Abort):
280 """error raised when a pushkey part failed to update a value"""
272 """error raised when a pushkey part failed to update a value"""
281
273
282 def __init__(self, partid, namespace=None, key=None, new=None, old=None,
274 def __init__(self, partid, namespace=None, key=None, new=None, old=None,
283 ret=None):
275 ret=None):
284 self.partid = partid
276 self.partid = partid
285 self.namespace = namespace
277 self.namespace = namespace
286 self.key = key
278 self.key = key
287 self.new = new
279 self.new = new
288 self.old = old
280 self.old = old
289 self.ret = ret
281 self.ret = ret
290 # no i18n expected to be processed into a better message
282 # no i18n expected to be processed into a better message
291 Abort.__init__(self, 'failed to update value for "%s/%s"'
283 Abort.__init__(self, 'failed to update value for "%s/%s"'
292 % (namespace, key))
284 % (namespace, key))
293
285
294 class CensoredNodeError(StorageError):
286 class CensoredNodeError(StorageError):
295 """error raised when content verification fails on a censored node
287 """error raised when content verification fails on a censored node
296
288
297 Also contains the tombstone data substituted for the uncensored data.
289 Also contains the tombstone data substituted for the uncensored data.
298 """
290 """
299
291
300 def __init__(self, filename, node, tombstone):
292 def __init__(self, filename, node, tombstone):
301 from .node import short
293 from .node import short
302 StorageError.__init__(self, '%s:%s' % (filename, short(node)))
294 StorageError.__init__(self, '%s:%s' % (filename, short(node)))
303 self.tombstone = tombstone
295 self.tombstone = tombstone
304
296
305 class CensoredBaseError(StorageError):
297 class CensoredBaseError(StorageError):
306 """error raised when a delta is rejected because its base is censored
298 """error raised when a delta is rejected because its base is censored
307
299
308 A delta based on a censored revision must be formed as single patch
300 A delta based on a censored revision must be formed as single patch
309 operation which replaces the entire base with new content. This ensures
301 operation which replaces the entire base with new content. This ensures
310 the delta may be applied by clones which have not censored the base.
302 the delta may be applied by clones which have not censored the base.
311 """
303 """
312
304
313 class InvalidBundleSpecification(Exception):
305 class InvalidBundleSpecification(Exception):
314 """error raised when a bundle specification is invalid.
306 """error raised when a bundle specification is invalid.
315
307
316 This is used for syntax errors as opposed to support errors.
308 This is used for syntax errors as opposed to support errors.
317 """
309 """
318 __bytes__ = _tobytes
310 __bytes__ = _tobytes
319
311
320 class UnsupportedBundleSpecification(Exception):
312 class UnsupportedBundleSpecification(Exception):
321 """error raised when a bundle specification is not supported."""
313 """error raised when a bundle specification is not supported."""
322 __bytes__ = _tobytes
314 __bytes__ = _tobytes
323
315
324 class CorruptedState(Exception):
316 class CorruptedState(Exception):
325 """error raised when a command is not able to read its state from file"""
317 """error raised when a command is not able to read its state from file"""
326 __bytes__ = _tobytes
318 __bytes__ = _tobytes
327
319
328 class PeerTransportError(Abort):
320 class PeerTransportError(Abort):
329 """Transport-level I/O error when communicating with a peer repo."""
321 """Transport-level I/O error when communicating with a peer repo."""
330
322
331 class InMemoryMergeConflictsError(Exception):
323 class InMemoryMergeConflictsError(Exception):
332 """Exception raised when merge conflicts arose during an in-memory merge."""
324 """Exception raised when merge conflicts arose during an in-memory merge."""
333 __bytes__ = _tobytes
325 __bytes__ = _tobytes
334
326
335 class WireprotoCommandError(Exception):
327 class WireprotoCommandError(Exception):
336 """Represents an error during execution of a wire protocol command.
328 """Represents an error during execution of a wire protocol command.
337
329
338 Should only be thrown by wire protocol version 2 commands.
330 Should only be thrown by wire protocol version 2 commands.
339
331
340 The error is a formatter string and an optional iterable of arguments.
332 The error is a formatter string and an optional iterable of arguments.
341 """
333 """
342 def __init__(self, message, args=None):
334 def __init__(self, message, args=None):
343 self.message = message
335 self.message = message
344 self.messageargs = args
336 self.messageargs = args
General Comments 0
You need to be logged in to leave comments. Login now