How to get inner exception traceback

T

Thomas Guettler

Hi,

How can you get the traceback of the inner exception?

try:
try:
import does_not_exit
except ImportError:
raise Exception("something wrong")
except:
...


Background: In Django some exceptions are caught and a new
exception gets raised. Unfortunately the real error is hard
to find. Sometimes I help myself and change (in this example)
ImportError to e.g. IOError and then I can see the real root
of the problem. But maybe there is a way to get the inner
exception and its traceback. This could be displayed in the
debug view.

Thomas
 
P

Peter Otten

Thomas said:
How can you get the traceback of the inner exception?

You have to record it yourself or it will be lost.
try:
try:
import does_not_exit
except ImportError:
raise Exception("something wrong")
except:
...


Background: In Django some exceptions are caught and a new
exception gets raised. Unfortunately the real error is hard
to find. Sometimes I help myself and change (in this example)
ImportError to e.g. IOError and then I can see the real root
of the problem. But maybe there is a way to get the inner
exception and its traceback. This could be displayed in the
debug view.

You can get the current exception and traceback with

sys.exc_info()

and later print or format it using the traceback module.
.... 1/0
.... except Exception:
.... x = sys.exc_info()
.... raise ValueError
....
Traceback (most recent call last):
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero

Peter
 
B

bockman

Hi,

How can you get the traceback of the inner exception?

try:
     try:
         import does_not_exit
     except ImportError:
         raise Exception("something wrong")
except:
     ...

Background: In Django some exceptions are caught and a new
exception gets raised. Unfortunately the real error is hard
to find. Sometimes I help myself and change (in this example)
ImportError to e.g. IOError and then I can see the real root
of the problem. But maybe there is a way to get the inner
exception and its traceback. This could be displayed in the
debug view.

  Thomas

I'm not sure it ill work since sys.exc_info() might not return a deep
copy of the traceback info,
but you could try to store the inner exception and its traceback as
attributes of the outer exception:

class ReraisedException(Exception):
def __init__(self, message, exc_info):
Exception.__init__(self, message)
self.inner_exception = exc_info

try:
try:
import does_not_exit
except ImportError:
raise ReraisedException("Something wrong", sys.exc_info() )
except ReraisedException, e:
... # here you can use e.inner_exception
except:
...


Ciao
 
C

Christian Heimes

I'm not sure it ill work since sys.exc_info() might not return a deep
copy of the traceback info,
but you could try to store the inner exception and its traceback as
attributes of the outer exception:

class ReraisedException(Exception):
def __init__(self, message, exc_info):
Exception.__init__(self, message)
self.inner_exception = exc_info

try:
try:
import does_not_exit
except ImportError:
raise ReraisedException("Something wrong", sys.exc_info() )
except ReraisedException, e:
... # here you can use e.inner_exception
except:

This may lead to reference cycles, please read
http://docs.python.org/dev/library/sys.html#sys.exc_info

Christian
 
B

bockman

(e-mail address removed) schrieb:
:


This may lead to reference cycles, please readhttp://docs.python.org/dev/library/sys.html#sys.exc_info

Christian- Nascondi testo tra virgolette -

- Mostra testo tra virgolette -

Thanks. I was not aware of that (Last time I read that section, the
warning was not there).
I usually do something like that in my scripts:

try:
do_something()
except:
err, detail, tb = sys.exc_info()
print err, detail
traceback.print_tb(tb)

According to the document you linked to, also this causes circular
reference, although in my case
it is ininfluent , since I usually do it only before exiting a program
after a
fatal error.

However, this seems like a dark spot in the implementation of
CPython.
Do you now if this has/will be cleaned in Python 3.x ? I'd like to
see a 'print_tb'
method in the exception class, so that I could do something like this:

try:
do_something()
except Exception, e : # I know, in python 3.0 the syntax will be
different
print e
e.print_tb()


Ciao
 
G

Gabriel Genellina

How can you get the traceback of the inner exception?

try:
try:
import does_not_exit
except ImportError:
raise Exception("something wrong")
except:
...


Background: In Django some exceptions are caught and a new
exception gets raised. Unfortunately the real error is hard
to find. Sometimes I help myself and change (in this example)
ImportError to e.g. IOError and then I can see the real root
of the problem. But maybe there is a way to get the inner
exception and its traceback. This could be displayed in the
debug view.

You already got a couple ways to do it - but I'd ask why do you want to
mask the original exception? If you don't have anything valuable to do
with it, just don't catch it. Or raise the *same* exception+context,
perhaps after modifying it a bit:

try:
try:
import does_not_exist
except ImportError, e:
e.args = ("Something is wrong with the plugin system\nDetails: %s" %
e.args,)
raise # <-- note the "bare" raise
except:
import traceback
print "An error has occurred"
print sys.exc_info()[1]
print sys.exc_info()[0].__name__
traceback.print_tb(sys.exc_info()[2])
# or whatever you want to do with the exception
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top