Statistics
| Branch: | Tag: | Revision:

root / lib / errors.py @ 4008c8ed

History | View | Annotate | Download (9.2 kB)

1 2f31098c Iustin Pop
#
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Ganeti exception handling"""
23 a8083063 Iustin Pop
24 a8083063 Iustin Pop
25 5c983ee5 Iustin Pop
# OpPrereqError failure types
26 5c983ee5 Iustin Pop
27 104f4ca1 Iustin Pop
# resolver errors
28 104f4ca1 Iustin Pop
ECODE_RESOLVER = "resolver_error"
29 5c983ee5 Iustin Pop
# not enough resources (iallocator failure, disk space, memory, etc.)
30 5c983ee5 Iustin Pop
ECODE_NORES = "insufficient_resources"
31 5c983ee5 Iustin Pop
# wrong arguments (at syntax level)
32 5c983ee5 Iustin Pop
ECODE_INVAL = "wrong_input"
33 5c983ee5 Iustin Pop
# wrong entity state
34 5c983ee5 Iustin Pop
ECODE_STATE = "wrong_state"
35 5c983ee5 Iustin Pop
# entity not found
36 5c983ee5 Iustin Pop
ECODE_NOENT = "unknown_entity"
37 5c983ee5 Iustin Pop
# entity already exists
38 5c983ee5 Iustin Pop
ECODE_EXISTS = "already_exists"
39 5c983ee5 Iustin Pop
# resource not unique (e.g. MAC or IP duplication)
40 5c983ee5 Iustin Pop
ECODE_NOTUNIQUE = "resource_not_unique"
41 5c983ee5 Iustin Pop
# internal cluster error
42 5c983ee5 Iustin Pop
ECODE_FAULT = "internal_error"
43 5c983ee5 Iustin Pop
# environment error (e.g. node disk error)
44 5c983ee5 Iustin Pop
ECODE_ENVIRON = "environment_error"
45 5c983ee5 Iustin Pop
46 5c983ee5 Iustin Pop
47 a8083063 Iustin Pop
class GenericError(Exception):
48 a8083063 Iustin Pop
  """Base exception for Ganeti.
49 a8083063 Iustin Pop

50 a8083063 Iustin Pop
  """
51 a8083063 Iustin Pop
  pass
52 a8083063 Iustin Pop
53 a8083063 Iustin Pop
54 a8083063 Iustin Pop
class LVMError(GenericError):
55 a8083063 Iustin Pop
  """LVM-related exception.
56 a8083063 Iustin Pop

57 a8083063 Iustin Pop
  This exception codifies problems with LVM setup.
58 a8083063 Iustin Pop

59 a8083063 Iustin Pop
  """
60 a8083063 Iustin Pop
  pass
61 a8083063 Iustin Pop
62 a8083063 Iustin Pop
63 a8083063 Iustin Pop
class LockError(GenericError):
64 a8083063 Iustin Pop
  """Lock error exception.
65 a8083063 Iustin Pop

66 a8083063 Iustin Pop
  This signifies problems in the locking subsystem.
67 a8083063 Iustin Pop

68 a8083063 Iustin Pop
  """
69 a8083063 Iustin Pop
  pass
70 a8083063 Iustin Pop
71 a8083063 Iustin Pop
72 a8083063 Iustin Pop
class HypervisorError(GenericError):
73 a8083063 Iustin Pop
  """Hypervisor-related exception.
74 a8083063 Iustin Pop

75 a8083063 Iustin Pop
  This is raised in case we can't communicate with the hypervisor
76 a8083063 Iustin Pop
  properly.
77 a8083063 Iustin Pop

78 a8083063 Iustin Pop
  """
79 a8083063 Iustin Pop
  pass
80 a8083063 Iustin Pop
81 a8083063 Iustin Pop
82 a8083063 Iustin Pop
class ProgrammerError(GenericError):
83 a8083063 Iustin Pop
  """Programming-related error.
84 a8083063 Iustin Pop

85 a8083063 Iustin Pop
  This is raised in cases we determine that the calling conventions
86 a8083063 Iustin Pop
  have been violated, meaning we got some desynchronisation between
87 a8083063 Iustin Pop
  parts of our code. It signifies a real programming bug.
88 a8083063 Iustin Pop

89 a8083063 Iustin Pop
  """
90 a8083063 Iustin Pop
  pass
91 a8083063 Iustin Pop
92 a8083063 Iustin Pop
93 a8083063 Iustin Pop
class BlockDeviceError(GenericError):
94 a8083063 Iustin Pop
  """Block-device related exception.
95 a8083063 Iustin Pop

96 a8083063 Iustin Pop
  This is raised in case we can't setup the instance's block devices
97 a8083063 Iustin Pop
  properly.
98 a8083063 Iustin Pop

99 a8083063 Iustin Pop
  """
100 a8083063 Iustin Pop
  pass
101 a8083063 Iustin Pop
102 a8083063 Iustin Pop
103 a8083063 Iustin Pop
class ConfigurationError(GenericError):
104 a8083063 Iustin Pop
  """Configuration related exception.
105 a8083063 Iustin Pop

106 a8083063 Iustin Pop
  Things like having an instance with a primary node that doesn't
107 a8083063 Iustin Pop
  exist in the config or such raise this exception.
108 a8083063 Iustin Pop

109 a8083063 Iustin Pop
  """
110 a8083063 Iustin Pop
  pass
111 a8083063 Iustin Pop
112 a8083063 Iustin Pop
113 2c8a5690 Guido Trotter
class ReservationError(GenericError):
114 2c8a5690 Guido Trotter
  """Errors reserving a resource.
115 2c8a5690 Guido Trotter

116 2c8a5690 Guido Trotter
  """
117 2c8a5690 Guido Trotter
118 2c8a5690 Guido Trotter
119 a8083063 Iustin Pop
class RemoteError(GenericError):
120 a8083063 Iustin Pop
  """Programming-related error on remote call.
121 a8083063 Iustin Pop

122 a8083063 Iustin Pop
  This is raised when an unhandled error occurs in a call to a
123 a8083063 Iustin Pop
  remote node.  It usually signifies a real programming bug.
124 a8083063 Iustin Pop

125 a8083063 Iustin Pop
  """
126 a8083063 Iustin Pop
  pass
127 a8083063 Iustin Pop
128 a8083063 Iustin Pop
129 f4a2f532 Guido Trotter
class SignatureError(GenericError):
130 f4a2f532 Guido Trotter
  """Error authenticating a remote message.
131 f4a2f532 Guido Trotter

132 f4a2f532 Guido Trotter
  This is raised when the hmac signature on a message doesn't verify correctly
133 f4a2f532 Guido Trotter
  to the message itself. It can happen because of network unreliability or
134 f4a2f532 Guido Trotter
  because of spurious traffic.
135 f4a2f532 Guido Trotter

136 f4a2f532 Guido Trotter
  """
137 f4a2f532 Guido Trotter
  pass
138 f4a2f532 Guido Trotter
139 f4a2f532 Guido Trotter
140 a8083063 Iustin Pop
class ParameterError(GenericError):
141 a8083063 Iustin Pop
  """A passed parameter to a command is invalid.
142 a8083063 Iustin Pop

143 a8083063 Iustin Pop
  This is raised when the parameter passed to a request function is
144 a8083063 Iustin Pop
  invalid. Correct code should have verified this before passing the
145 a8083063 Iustin Pop
  request structure.
146 a8083063 Iustin Pop

147 a8083063 Iustin Pop
  The argument to this exception should be the parameter name.
148 a8083063 Iustin Pop

149 a8083063 Iustin Pop
  """
150 a8083063 Iustin Pop
  pass
151 a8083063 Iustin Pop
152 a8083063 Iustin Pop
153 a8083063 Iustin Pop
class OpPrereqError(GenericError):
154 a8083063 Iustin Pop
  """Prerequisites for the OpCode are not fulfilled.
155 a8083063 Iustin Pop

156 5c983ee5 Iustin Pop
  This exception will have either one or two arguments. For the
157 5c983ee5 Iustin Pop
  two-argument construction, the second argument should be one of the
158 5c983ee5 Iustin Pop
  ECODE_* codes.
159 5c983ee5 Iustin Pop

160 a8083063 Iustin Pop
  """
161 a8083063 Iustin Pop
162 098c0958 Michael Hanselmann
163 a8083063 Iustin Pop
class OpExecError(GenericError):
164 a8083063 Iustin Pop
  """Error during OpCode execution.
165 a8083063 Iustin Pop

166 a8083063 Iustin Pop
  """
167 a8083063 Iustin Pop
168 098c0958 Michael Hanselmann
169 a8083063 Iustin Pop
class OpCodeUnknown(GenericError):
170 a8083063 Iustin Pop
  """Unknown opcode submitted.
171 a8083063 Iustin Pop

172 a8083063 Iustin Pop
  This signifies a mismatch between the definitions on the client and
173 a8083063 Iustin Pop
  server side.
174 a8083063 Iustin Pop

175 a8083063 Iustin Pop
  """
176 a8083063 Iustin Pop
177 098c0958 Michael Hanselmann
178 685ee993 Iustin Pop
class JobLost(GenericError):
179 685ee993 Iustin Pop
  """Submitted job lost.
180 685ee993 Iustin Pop

181 685ee993 Iustin Pop
  The job was submitted but it cannot be found in the current job
182 685ee993 Iustin Pop
  list.
183 685ee993 Iustin Pop

184 685ee993 Iustin Pop
  """
185 685ee993 Iustin Pop
186 685ee993 Iustin Pop
187 3d6c5566 Guido Trotter
class JobFileCorrupted(GenericError):
188 3d6c5566 Guido Trotter
  """Job file could not be properly decoded/restored.
189 3d6c5566 Guido Trotter

190 3d6c5566 Guido Trotter
  """
191 3d6c5566 Guido Trotter
192 3d6c5566 Guido Trotter
193 89e1fc26 Iustin Pop
class ResolverError(GenericError):
194 89e1fc26 Iustin Pop
  """Host name cannot be resolved.
195 89e1fc26 Iustin Pop

196 89e1fc26 Iustin Pop
  This is not a normal situation for Ganeti, as we rely on having a
197 89e1fc26 Iustin Pop
  working resolver.
198 89e1fc26 Iustin Pop

199 89e1fc26 Iustin Pop
  The non-resolvable hostname is available as the first element of the
200 89e1fc26 Iustin Pop
  args tuple; the other two elements of the tuple are the first two
201 89e1fc26 Iustin Pop
  args of the socket.gaierror exception (error code and description).
202 89e1fc26 Iustin Pop

203 89e1fc26 Iustin Pop
  """
204 89e1fc26 Iustin Pop
205 89e1fc26 Iustin Pop
206 a8083063 Iustin Pop
class HooksFailure(GenericError):
207 a8083063 Iustin Pop
  """A generic hook failure.
208 a8083063 Iustin Pop

209 a8083063 Iustin Pop
  This signifies usually a setup misconfiguration.
210 a8083063 Iustin Pop

211 a8083063 Iustin Pop
  """
212 a8083063 Iustin Pop
213 098c0958 Michael Hanselmann
214 a8083063 Iustin Pop
class HooksAbort(HooksFailure):
215 a8083063 Iustin Pop
  """A required hook has failed.
216 a8083063 Iustin Pop

217 a8083063 Iustin Pop
  This caused an abort of the operation in the initial phase. This
218 a8083063 Iustin Pop
  exception always has an attribute args which is a list of tuples of:
219 a8083063 Iustin Pop
    - node: the source node on which this hooks has failed
220 a8083063 Iustin Pop
    - script: the name of the script which aborted the run
221 a8083063 Iustin Pop

222 a8083063 Iustin Pop
  """
223 a8083063 Iustin Pop
224 098c0958 Michael Hanselmann
225 a8083063 Iustin Pop
class UnitParseError(GenericError):
226 a8083063 Iustin Pop
  """Unable to parse size unit.
227 a8083063 Iustin Pop

228 a8083063 Iustin Pop
  """
229 a8083063 Iustin Pop
230 ac2d0fe4 Michael Hanselmann
231 31155d60 Balazs Lecz
class ParseError(GenericError):
232 31155d60 Balazs Lecz
  """Generic parse error.
233 31155d60 Balazs Lecz

234 31155d60 Balazs Lecz
  Raised when unable to parse user input.
235 31155d60 Balazs Lecz

236 31155d60 Balazs Lecz
  """
237 31155d60 Balazs Lecz
238 31155d60 Balazs Lecz
239 a5728081 Guido Trotter
class TypeEnforcementError(GenericError):
240 a5728081 Guido Trotter
  """Unable to enforce data type.
241 a5728081 Guido Trotter

242 a5728081 Guido Trotter
  """
243 a8083063 Iustin Pop
244 ac2d0fe4 Michael Hanselmann
245 a8083063 Iustin Pop
class SshKeyError(GenericError):
246 a8083063 Iustin Pop
  """Invalid SSH key.
247 b0059682 Guido Trotter

248 a8083063 Iustin Pop
  """
249 5c947f38 Iustin Pop
250 5c947f38 Iustin Pop
251 5c947f38 Iustin Pop
class TagError(GenericError):
252 5c947f38 Iustin Pop
  """Generic tag error.
253 5c947f38 Iustin Pop

254 5c947f38 Iustin Pop
  The argument to this exception will show the exact error.
255 5c947f38 Iustin Pop

256 5c947f38 Iustin Pop
  """
257 7bca53e4 Michael Hanselmann
258 7bca53e4 Michael Hanselmann
259 7bca53e4 Michael Hanselmann
class CommandError(GenericError):
260 7bca53e4 Michael Hanselmann
  """External command error.
261 7bca53e4 Michael Hanselmann

262 7bca53e4 Michael Hanselmann
  """
263 e50bdd68 Guido Trotter
264 e50bdd68 Guido Trotter
265 ac2d0fe4 Michael Hanselmann
class StorageError(GenericError):
266 ac2d0fe4 Michael Hanselmann
  """Storage-related exception.
267 ac2d0fe4 Michael Hanselmann

268 ac2d0fe4 Michael Hanselmann
  """
269 ac2d0fe4 Michael Hanselmann
270 589dee9a Guido Trotter
271 589dee9a Guido Trotter
class InotifyError(GenericError):
272 589dee9a Guido Trotter
  """Error raised when there is a failure setting up an inotify watcher.
273 589dee9a Guido Trotter

274 589dee9a Guido Trotter
  """
275 589dee9a Guido Trotter
276 ac2d0fe4 Michael Hanselmann
277 e50bdd68 Guido Trotter
class QuitGanetiException(Exception):
278 e50bdd68 Guido Trotter
  """Signal that Ganeti that it must quit.
279 e50bdd68 Guido Trotter

280 0623d351 Iustin Pop
  This is not necessarily an error (and thus not a subclass of
281 0623d351 Iustin Pop
  GenericError), but it's an exceptional circumstance and it is thus
282 0623d351 Iustin Pop
  treated. This instance should be instantiated with two values. The
283 0623d351 Iustin Pop
  first one will specify the return code to the caller, and the second
284 0623d351 Iustin Pop
  one will be the returned result (either as an error or as a normal
285 0623d351 Iustin Pop
  result). Usually only the leave cluster rpc call should return
286 0623d351 Iustin Pop
  status True (as there it's expected we quit), every other call will
287 0623d351 Iustin Pop
  return status False (as a critical error was encountered).
288 e50bdd68 Guido Trotter

289 c41eea6e Iustin Pop
  Examples::
290 c41eea6e Iustin Pop

291 e50bdd68 Guido Trotter
    # Return a result of "True" to the caller, but quit ganeti afterwards
292 0623d351 Iustin Pop
    raise QuitGanetiException(True, None)
293 e50bdd68 Guido Trotter
    # Send an error to the caller, and quit ganeti
294 0623d351 Iustin Pop
    raise QuitGanetiException(False, "Fatal safety violation, shutting down")
295 e50bdd68 Guido Trotter

296 e50bdd68 Guido Trotter
  """
297 e50bdd68 Guido Trotter
298 f1da30e6 Michael Hanselmann
299 d11bda8d Iustin Pop
class JobQueueError(GenericError):
300 f1da30e6 Michael Hanselmann
  """Job queue error.
301 f1da30e6 Michael Hanselmann

302 f1da30e6 Michael Hanselmann
  """
303 6797ec29 Iustin Pop
304 6797ec29 Iustin Pop
305 686d7433 Iustin Pop
class JobQueueDrainError(JobQueueError):
306 686d7433 Iustin Pop
  """Job queue is marked for drain error.
307 686d7433 Iustin Pop

308 686d7433 Iustin Pop
  This is raised when a job submission attempt is made but the queue
309 686d7433 Iustin Pop
  is marked for drain.
310 686d7433 Iustin Pop

311 686d7433 Iustin Pop
  """
312 686d7433 Iustin Pop
313 686d7433 Iustin Pop
314 f87b405e Michael Hanselmann
class JobQueueFull(JobQueueError):
315 f87b405e Michael Hanselmann
  """Job queue full error.
316 f87b405e Michael Hanselmann

317 f87b405e Michael Hanselmann
  Raised when job queue size reached its hard limit.
318 f87b405e Michael Hanselmann

319 f87b405e Michael Hanselmann
  """
320 f87b405e Michael Hanselmann
321 f87b405e Michael Hanselmann
322 b125e3b3 Guido Trotter
class ConfdRequestError(GenericError):
323 b125e3b3 Guido Trotter
  """A request error in Ganeti confd.
324 b125e3b3 Guido Trotter

325 b125e3b3 Guido Trotter
  Events that should make confd abort the current request and proceed serving
326 b125e3b3 Guido Trotter
  different ones.
327 b125e3b3 Guido Trotter

328 b125e3b3 Guido Trotter
  """
329 b125e3b3 Guido Trotter
330 b125e3b3 Guido Trotter
331 9748ab35 Guido Trotter
class ConfdMagicError(GenericError):
332 9748ab35 Guido Trotter
  """A magic fourcc error in Ganeti confd.
333 9748ab35 Guido Trotter

334 9748ab35 Guido Trotter
  Errors processing the fourcc in ganeti confd datagrams.
335 9748ab35 Guido Trotter

336 9748ab35 Guido Trotter
  """
337 9748ab35 Guido Trotter
338 9748ab35 Guido Trotter
339 e4ccf6cd Guido Trotter
class ConfdClientError(GenericError):
340 e4ccf6cd Guido Trotter
  """A magic fourcc error in Ganeti confd.
341 e4ccf6cd Guido Trotter

342 e4ccf6cd Guido Trotter
  Errors in the confd client library.
343 e4ccf6cd Guido Trotter

344 e4ccf6cd Guido Trotter
  """
345 e4ccf6cd Guido Trotter
346 e4ccf6cd Guido Trotter
347 c8eded0b Guido Trotter
class UdpDataSizeError(GenericError):
348 c8eded0b Guido Trotter
  """UDP payload too big.
349 c8eded0b Guido Trotter

350 c8eded0b Guido Trotter
  """
351 c8eded0b Guido Trotter
352 c8eded0b Guido Trotter
353 4c32a8bd Luca Bigliardi
class NoCtypesError(GenericError):
354 4c32a8bd Luca Bigliardi
  """python ctypes module is not found in the system.
355 4c32a8bd Luca Bigliardi

356 4c32a8bd Luca Bigliardi
  """
357 4c32a8bd Luca Bigliardi
358 4c32a8bd Luca Bigliardi
359 6797ec29 Iustin Pop
# errors should be added above
360 6797ec29 Iustin Pop
361 6797ec29 Iustin Pop
362 6797ec29 Iustin Pop
def GetErrorClass(name):
363 6797ec29 Iustin Pop
  """Return the class of an exception.
364 6797ec29 Iustin Pop

365 6797ec29 Iustin Pop
  Given the class name, return the class itself.
366 6797ec29 Iustin Pop

367 6797ec29 Iustin Pop
  @type name: str
368 6797ec29 Iustin Pop
  @param name: the exception name
369 6797ec29 Iustin Pop
  @rtype: class
370 6797ec29 Iustin Pop
  @return: the actual class, or None if not found
371 6797ec29 Iustin Pop

372 6797ec29 Iustin Pop
  """
373 6797ec29 Iustin Pop
  item = globals().get(name, None)
374 6797ec29 Iustin Pop
  if item is not None:
375 6797ec29 Iustin Pop
    if not (isinstance(item, type(Exception)) and
376 6797ec29 Iustin Pop
            issubclass(item, GenericError)):
377 6797ec29 Iustin Pop
      item = None
378 6797ec29 Iustin Pop
  return item
379 6956e9cd Iustin Pop
380 6956e9cd Iustin Pop
381 6956e9cd Iustin Pop
def EncodeException(err):
382 6956e9cd Iustin Pop
  """Encodes an exception into a format that L{MaybeRaise} will recognise.
383 6956e9cd Iustin Pop

384 6956e9cd Iustin Pop
  The passed L{err} argument will be formatted as a tuple (exception
385 6956e9cd Iustin Pop
  name, arguments) that the MaybeRaise function will recognise.
386 6956e9cd Iustin Pop

387 6956e9cd Iustin Pop
  @type err: GenericError child
388 6956e9cd Iustin Pop
  @param err: usually a child of GenericError (but any exception
389 6956e9cd Iustin Pop
      will be accepted)
390 6956e9cd Iustin Pop
  @rtype: tuple
391 6956e9cd Iustin Pop
  @return: tuple of (exception name, exception arguments)
392 6956e9cd Iustin Pop

393 6956e9cd Iustin Pop
  """
394 6956e9cd Iustin Pop
  return (err.__class__.__name__, err.args)
395 6956e9cd Iustin Pop
396 6956e9cd Iustin Pop
397 84f790e6 Michael Hanselmann
def GetEncodedError(result):
398 84f790e6 Michael Hanselmann
  """If this looks like an encoded Ganeti exception, return it.
399 6956e9cd Iustin Pop

400 6956e9cd Iustin Pop
  This function tries to parse the passed argument and if it looks
401 84f790e6 Michael Hanselmann
  like an encoding done by EncodeException, it will return the class
402 84f790e6 Michael Hanselmann
  object and arguments.
403 6956e9cd Iustin Pop

404 6956e9cd Iustin Pop
  """
405 6956e9cd Iustin Pop
  tlt = (tuple, list)
406 6956e9cd Iustin Pop
  if (isinstance(result, tlt) and len(result) == 2 and
407 6956e9cd Iustin Pop
      isinstance(result[1], tlt)):
408 6956e9cd Iustin Pop
    # custom ganeti errors
409 84f790e6 Michael Hanselmann
    errcls = GetErrorClass(result[0])
410 84f790e6 Michael Hanselmann
    if errcls:
411 84f790e6 Michael Hanselmann
      return (errcls, tuple(result[1]))
412 84f790e6 Michael Hanselmann
413 84f790e6 Michael Hanselmann
  return None
414 84f790e6 Michael Hanselmann
415 84f790e6 Michael Hanselmann
416 84f790e6 Michael Hanselmann
def MaybeRaise(result):
417 84f790e6 Michael Hanselmann
  """If this looks like an encoded Ganeti exception, raise it.
418 84f790e6 Michael Hanselmann

419 84f790e6 Michael Hanselmann
  This function tries to parse the passed argument and if it looks
420 84f790e6 Michael Hanselmann
  like an encoding done by EncodeException, it will re-raise it.
421 84f790e6 Michael Hanselmann

422 84f790e6 Michael Hanselmann
  """
423 84f790e6 Michael Hanselmann
  error = GetEncodedError(result)
424 84f790e6 Michael Hanselmann
  if error:
425 84f790e6 Michael Hanselmann
    (errcls, args) = error
426 84f790e6 Michael Hanselmann
    raise errcls, args