anijhaw anijhaw - 2 months ago 7
Python Question

Adding information to an exception?

EDIT: I am running python 2.6

I want to achieve something like this:

def foo():
try:
raise IOError('Stuff ')
except:
raise

def bar(arg1):
try:
foo()
except Exception as e:
e.message = e.message + 'happens at %s' % arg1
raise

bar('arg1')


Traceback...
IOError('Stuff Happens at arg1')


But what I get is:

Traceback..
IOError('Stuff')


Any clues as to how to achieve this?

Answer

I'd do it like this so changing its type in foo() won't require also changing it in bar().

def foo():
   try:
       raise IOError('Stuff')
   except:
       raise

def bar(arg1):
    try:
       foo()
    except Exception as e:
       raise type(e)(e.message + ' happens at %s' % arg1)

bar('arg1')
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    bar('arg1')
  File "test.py", line 11, in bar
    raise type(e)(e.message + ' happens at %s' % arg1)
IOError: Stuff happens at arg1

Update

Here's a slight modification that preserves the original traceback:

...
def bar(arg1):
    try:
       foo()
    except Exception as e:
        import sys
        raise type(e), type(e)(e.message + 
                               ' happens at %s' % arg1), sys.exc_info()[2]

bar('arg1')
Traceback (most recent call last):
  File "test.py", line 16, in <module>
    bar('arg1')
  File "test.py", line 11, in bar
    foo()
  File "test.py", line 5, in foo
    raise IOError('Stuff')
IOError: Stuff happens at arg1

Update 2

For Python 3.x, the code in my first update is syntactically incorrect plus the idea of having a message attribute on BaseException was retracted in a change to PEP 352 on 2012-05-16 (the update was posted on 2012-03-12). So, currently in Python 3.4.0 anyway, you'd need to do something along these lines to preserve the traceback and not hardcode the type of exception in function bar():

# for Python 3.0+
...
def bar(arg1):
    try:
       foo()
    except Exception as e:
        import sys
        raise type(e)(str(e) +
                      ' happens at %s' % arg1).with_traceback(sys.exc_info()[2])

bar('arg1')
Comments