##// END OF EJS Templates
error: make HintException a mix-in class not derived from BaseException (API)...
Yuya Nishihara -
r29509:945b4c14 default
parent child Browse files
Show More
@@ -1,237 +1,242 b''
1 1 # error.py - Mercurial exceptions
2 2 #
3 3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 """Mercurial exceptions.
9 9
10 10 This allows us to catch exceptions at higher levels without forcing
11 11 imports.
12 12 """
13 13
14 14 from __future__ import absolute_import
15 15
16 16 # Do not import anything here, please
17 17
18 class HintException(Exception):
18 class Hint(object):
19 """Mix-in to provide a hint of an error
20
21 This should come first in the inheritance list to consume **kw and pass
22 only *args to the exception class.
23 """
19 24 def __init__(self, *args, **kw):
20 Exception.__init__(self, *args)
25 super(Hint, self).__init__(*args)
21 26 self.hint = kw.get('hint')
22 27
23 class RevlogError(HintException):
28 class RevlogError(Hint, Exception):
24 29 pass
25 30
26 31 class FilteredIndexError(IndexError):
27 32 pass
28 33
29 34 class LookupError(RevlogError, KeyError):
30 35 def __init__(self, name, index, message):
31 36 self.name = name
32 37 self.index = index
33 38 # this can't be called 'message' because at least some installs of
34 39 # Python 2.6+ complain about the 'message' property being deprecated
35 40 self.lookupmessage = message
36 41 if isinstance(name, str) and len(name) == 20:
37 42 from .node import short
38 43 name = short(name)
39 44 RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
40 45
41 46 def __str__(self):
42 47 return RevlogError.__str__(self)
43 48
44 49 class FilteredLookupError(LookupError):
45 50 pass
46 51
47 52 class ManifestLookupError(LookupError):
48 53 pass
49 54
50 55 class CommandError(Exception):
51 56 """Exception raised on errors in parsing the command line."""
52 57
53 class InterventionRequired(HintException):
58 class InterventionRequired(Hint, Exception):
54 59 """Exception raised when a command requires human intervention."""
55 60
56 class Abort(HintException):
61 class Abort(Hint, Exception):
57 62 """Raised if a command needs to print an error and exit."""
58 63
59 64 class HookLoadError(Abort):
60 65 """raised when loading a hook fails, aborting an operation
61 66
62 67 Exists to allow more specialized catching."""
63 68
64 69 class HookAbort(Abort):
65 70 """raised when a validation hook fails, aborting an operation
66 71
67 72 Exists to allow more specialized catching."""
68 73
69 74 class ConfigError(Abort):
70 75 """Exception raised when parsing config files"""
71 76
72 77 class UpdateAbort(Abort):
73 78 """Raised when an update is aborted for destination issue"""
74 79
75 80 class MergeDestAbort(Abort):
76 81 """Raised when an update is aborted for destination issues"""
77 82
78 83 class NoMergeDestAbort(MergeDestAbort):
79 84 """Raised when an update is aborted because there is nothing to merge"""
80 85
81 86 class ManyMergeDestAbort(MergeDestAbort):
82 87 """Raised when an update is aborted because destination is ambigious"""
83 88
84 89 class ResponseExpected(Abort):
85 90 """Raised when an EOF is received for a prompt"""
86 91 def __init__(self):
87 92 from .i18n import _
88 93 Abort.__init__(self, _('response expected'))
89 94
90 class OutOfBandError(HintException):
95 class OutOfBandError(Hint, Exception):
91 96 """Exception raised when a remote repo reports failure"""
92 97
93 class ParseError(HintException):
98 class ParseError(Hint, Exception):
94 99 """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
95 100
96 101 class UnknownIdentifier(ParseError):
97 102 """Exception raised when a {rev,file}set references an unknown identifier"""
98 103
99 104 def __init__(self, function, symbols):
100 105 from .i18n import _
101 106 ParseError.__init__(self, _("unknown identifier: %s") % function)
102 107 self.function = function
103 108 self.symbols = symbols
104 109
105 class RepoError(HintException):
110 class RepoError(Hint, Exception):
106 111 pass
107 112
108 113 class RepoLookupError(RepoError):
109 114 pass
110 115
111 116 class FilteredRepoLookupError(RepoLookupError):
112 117 pass
113 118
114 119 class CapabilityError(RepoError):
115 120 pass
116 121
117 122 class RequirementError(RepoError):
118 123 """Exception raised if .hg/requires has an unknown entry."""
119 124
120 125 class UnsupportedMergeRecords(Abort):
121 126 def __init__(self, recordtypes):
122 127 from .i18n import _
123 128 self.recordtypes = sorted(recordtypes)
124 129 s = ' '.join(self.recordtypes)
125 130 Abort.__init__(
126 131 self, _('unsupported merge state records: %s') % s,
127 132 hint=_('see https://mercurial-scm.org/wiki/MergeStateRecords for '
128 133 'more information'))
129 134
130 135 class LockError(IOError):
131 136 def __init__(self, errno, strerror, filename, desc):
132 137 IOError.__init__(self, errno, strerror, filename)
133 138 self.desc = desc
134 139
135 140 class LockHeld(LockError):
136 141 def __init__(self, errno, filename, desc, locker):
137 142 LockError.__init__(self, errno, 'Lock held', filename, desc)
138 143 self.locker = locker
139 144
140 145 class LockUnavailable(LockError):
141 146 pass
142 147
143 148 # LockError is for errors while acquiring the lock -- this is unrelated
144 149 class LockInheritanceContractViolation(RuntimeError):
145 150 pass
146 151
147 152 class ResponseError(Exception):
148 153 """Raised to print an error with part of output and exit."""
149 154
150 155 class UnknownCommand(Exception):
151 156 """Exception raised if command is not in the command table."""
152 157
153 158 class AmbiguousCommand(Exception):
154 159 """Exception raised if command shortcut matches more than one command."""
155 160
156 161 # derived from KeyboardInterrupt to simplify some breakout code
157 162 class SignalInterrupt(KeyboardInterrupt):
158 163 """Exception raised on SIGTERM and SIGHUP."""
159 164
160 165 class SignatureError(Exception):
161 166 pass
162 167
163 168 class PushRaced(RuntimeError):
164 169 """An exception raised during unbundling that indicate a push race"""
165 170
166 171 # bundle2 related errors
167 172 class BundleValueError(ValueError):
168 173 """error raised when bundle2 cannot be processed"""
169 174
170 175 class BundleUnknownFeatureError(BundleValueError):
171 176 def __init__(self, parttype=None, params=(), values=()):
172 177 self.parttype = parttype
173 178 self.params = params
174 179 self.values = values
175 180 if self.parttype is None:
176 181 msg = 'Stream Parameter'
177 182 else:
178 183 msg = parttype
179 184 entries = self.params
180 185 if self.params and self.values:
181 186 assert len(self.params) == len(self.values)
182 187 entries = []
183 188 for idx, par in enumerate(self.params):
184 189 val = self.values[idx]
185 190 if val is None:
186 191 entries.append(val)
187 192 else:
188 193 entries.append("%s=%r" % (par, val))
189 194 if entries:
190 195 msg = '%s - %s' % (msg, ', '.join(entries))
191 196 ValueError.__init__(self, msg)
192 197
193 198 class ReadOnlyPartError(RuntimeError):
194 199 """error raised when code tries to alter a part being generated"""
195 200
196 201 class PushkeyFailed(Abort):
197 202 """error raised when a pushkey part failed to update a value"""
198 203
199 204 def __init__(self, partid, namespace=None, key=None, new=None, old=None,
200 205 ret=None):
201 206 self.partid = partid
202 207 self.namespace = namespace
203 208 self.key = key
204 209 self.new = new
205 210 self.old = old
206 211 self.ret = ret
207 212 # no i18n expected to be processed into a better message
208 213 Abort.__init__(self, 'failed to update value for "%s/%s"'
209 214 % (namespace, key))
210 215
211 216 class CensoredNodeError(RevlogError):
212 217 """error raised when content verification fails on a censored node
213 218
214 219 Also contains the tombstone data substituted for the uncensored data.
215 220 """
216 221
217 222 def __init__(self, filename, node, tombstone):
218 223 from .node import short
219 224 RevlogError.__init__(self, '%s:%s' % (filename, short(node)))
220 225 self.tombstone = tombstone
221 226
222 227 class CensoredBaseError(RevlogError):
223 228 """error raised when a delta is rejected because its base is censored
224 229
225 230 A delta based on a censored revision must be formed as single patch
226 231 operation which replaces the entire base with new content. This ensures
227 232 the delta may be applied by clones which have not censored the base.
228 233 """
229 234
230 235 class InvalidBundleSpecification(Exception):
231 236 """error raised when a bundle specification is invalid.
232 237
233 238 This is used for syntax errors as opposed to support errors.
234 239 """
235 240
236 241 class UnsupportedBundleSpecification(Exception):
237 242 """error raised when a bundle specification is not supported."""
General Comments 0
You need to be logged in to leave comments. Login now