16

So I basically have to isolate 2 layers of the application from one another by exceptions.

I have this WLST 12c script (python 2.2), that goes like

try:
    something something...
except java.lang.UnsuportedOpperationException, (a, b):
    pass
except java.lang.reflect.UndeclaredThrowableException, (a, b):
    pass

I'd like to be able to re-raise one of my own types of exception, that contains a message about what caused the previous exception (and no, i don't know what the a and b parameters are, but i'm guessing one of them should be the exception description).

I'm a java guy myself, so i am looking forward to something like

try {
    something something...
} catch (Exception e) {
    throw new RuntimeException(e, "something horrible happened");
}
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
vlad-ardelean
  • 7,480
  • 15
  • 80
  • 124
  • 1
    Why exactly are you using python 2.2? The most recent 2.2 release was 2003. There's no current distributions that ship that for their current version as far as I'm aware... – Daenyth May 11 '12 at 22:26
  • that actually looks like it's using a `Jython` interpreter which may be behind CPython in terms of version numbers – Andre Holzner Feb 05 '14 at 14:15

5 Answers5

32

Although this is an old post, there is a much more simple answer to the original question. To rethrow an exception after catching it, just use "raise" with no arguments. The original stack trace will be preserved.

normaldotcom
  • 329
  • 3
  • 2
10

I hope I got the question right.

I'm not sure about Python 2.2 specifics, but this says you can handle exceptions the same way it's done in more recent versions:

try:
    do_stuff()
except ErrorToCatch, e:
    raise ExceptionToThrow(e)

Or maybe the last line should be raise ExceptionToThrow(str(e)). That depends on how your exception is defined. Example:

try:
    raise TypeError('foo')
except TypeError, t:
    raise ValueError(t)

This raises ValueError('foo').

Hope it helps :)

Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
  • 1
    The method without str() is best; see http://www.python.org/dev/peps/pep-3134/ . Also @vlad-ardelean: you can use ExceptionToThrow e.__cause__ to get the ErrorToCatch – Riking May 11 '12 at 17:22
  • 2
    Note that this discards information about where the original exception occurred, but that sounds like what the OP is asking for. – jrennie May 11 '12 at 17:30
4

The idiom

try:
   ...
except SomeException:
   ...
   raise

mentioned by @normaldotcom rethrows the error that has been catched as-is, without any modification. It does not answer to the OP, "How do I create a new exception that contain information about an exception that has been catched".

Indeed in some situations, one would like to create a new exception, typically to regroup many possible sources of internal errors into a single exception with a clearer message, while still keeping the traceback to the original error to enable debugging.

A way to achieve this is via the with_traceback method of BaseException. For example,

import sys

try:
  raise ValueError('internal error message')
except ValueError:
  tb = sys.exc_info()[2]
  raise Exception('new error message').with_traceback(tb)
P-Gn
  • 23,115
  • 9
  • 87
  • 104
4

I Python 3, the raise from construction does exactly what you ask for. It raises the new exception, saving the original exception in __cause__ attribute of the new one.

See here: https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement

>>> try:
...     print(1 / 0)
... except Exception as exc:
...     raise RuntimeError("Something bad happened") from exc
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened
C-F
  • 1,597
  • 16
  • 25
0
class MyException(Exception): pass

...

try:
    my_funcion(my_args)
except (IOError, KeyError, some_list_of_other_possible_exceptions), e:
    raise MyException("Uh oh")

You can extract information from the original exception, which here is bound to e, and then pass that on to your own exception when you raise it.

Michael Kent
  • 1,736
  • 12
  • 11