“Inner exception” (with traceback) in Python?

StackOverflow

My background is in C# and I"ve just recently started programming in Python. When an exception is thrown I typically want to wrap it in another exception that adds more information, while still showing the full stack trace. It"s quite easy in C#, but how do I do it in Python?

Eg. in C# I would do something like this:

try
{
  ProcessFile(filePath);
}
catch (Exception ex)
{
  throw new ApplicationException("Failed to process file " + filePath, ex);
}

In Python I can do something similar:

try:
  ProcessFile(filePath)
except Exception as e:
  raise Exception("Failed to process file " + filePath, e)

...but this loses the traceback of the inner exception!

Edit: I"d like to see both exception messages and both stack traces and correlate the two. That is, I want to see in the output that exception X occurred here and then exception Y there - same as I would in C#. Is this possible in Python 2.6? Looks like the best I can do so far (based on Glenn Maynard"s answer) is:

try:
  ProcessFile(filePath)
except Exception as e:
  raise Exception("Failed to process file" + filePath, e), None, sys.exc_info()[2]

This includes both the messages and both the tracebacks, but it doesn"t show which exception occurred where in the traceback.

Answer rating: 281

Python 3

In python 3 you can do the following:

try:
    raise MyExceptionToBeWrapped("I have twisted my ankle")

except MyExceptionToBeWrapped as e:

    raise MyWrapperException("I"m not in a good shape") from e

This will produce something like this:

   Traceback (most recent call last):
   ...
   MyExceptionToBeWrapped: ("I have twisted my ankle")

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

   Traceback (most recent call last):
   ...
   MyWrapperException: ("I"m not in a good shape")

Answer rating: 141

Python 2

It"s simple; pass the traceback as the third argument to raise.

import sys
class MyException(Exception): pass

try:
    raise TypeError("test")
except TypeError, e:
    raise MyException(), None, sys.exc_info()[2]

Always do this when catching one exception and re-raising another.





Get Solution for free from DataCamp guru