Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception traceback is hidden if not re-raised immediately

I've got a piece of code similar to this:

import sys  def func1():     func2()  def func2():     raise Exception('test error')  def main():     err = None      try:         func1()     except:         err = sys.exc_info()[1]         pass      # some extra processing, involving checking err details (if err is not None)      # need to re-raise err so caller can do its own handling     if err:         raise err  if __name__ == '__main__':     main() 

When func2 raises an exception I receive the following traceback:

Traceback (most recent call last):   File "err_test.py", line 25, in <module>     main()   File "err_test.py", line 22, in main     raise err Exception: test error 

From here I don't see where the exception is coming from. The original traceback is lost.

How can I preserve original traceback and re-raise it? I want to see something similar to this:

Traceback (most recent call last):   File "err_test.py", line 26, in <module>     main()   File "err_test.py", line 13, in main     func1()   File "err_test.py", line 4, in func1     func2()   File "err_test.py", line 7, in func2     raise Exception('test error') Exception: test error 
like image 806
parxier Avatar asked Jan 28 '11 05:01

parxier


People also ask

How do I fix Python traceback error?

If there is no variable defined with that name you will get a NameError exception. To fix the problem, in Python 2, you can use raw_input() . This returns the string entered by the user and does not attempt to evaluate it. Note that if you were using Python 3, input() behaves the same as raw_input() does in Python 2.

What happens if exception is raised?

The most common use of raise constructs an exception instance and raises it. When an exception is raised, no further statements in the current block of code are executed.

What are common traceback errors?

Some of the common traceback errors are:IndexError. KeyError. TypeError. valueError.

What happens if exception is not handled in Python?

Catching Exceptions in Python When an exception occurs, the Python interpreter stops the current process. It is handled by passing through the calling process. If not, the program will crash. For instance, a Python program has a function X that calls function Y, which in turn calls function Z.


2 Answers

A blank raise raises the last exception.

# need to re-raise err so caller can do its own handling if err:     raise 

If you use raise something Python has no way of knowing if something was an exception just caught before, or a new exception with a new stack trace. That's why there is the blank raise that preserves the stack trace.

Reference here

like image 115
Jochen Ritzel Avatar answered Nov 04 '22 18:11

Jochen Ritzel


It is possible to modify and rethrow an exception:

If no expressions are present, raise re-raises the last exception that was active in the current scope. If no exception is active in the current scope, a TypeError exception is raised indicating that this is an error (if running under IDLE, a Queue.Empty exception is raised instead).

Otherwise, raise evaluates the expressions to get three objects, using None as the value of omitted expressions. The first two objects are used to determine the type and value of the exception.

If a third object is present and not None, it must be a traceback object (see section The standard type hierarchy), and it is substituted instead of the current location as the place where the exception occurred. If the third object is present and not a traceback object or None, a TypeError exception is raised.

The three-expression form of raise is useful to re-raise an exception transparently in an except clause, but raise with no expressions should be preferred if the exception to be re-raised was the most recently active exception in the current scope.

So if you want to modify the exception and rethrow it, you can do this:

try:     buggy_code_which_throws_exception() except Exception as e:     raise Exception, "The code is buggy: %s" % e, sys.exc_info()[2] 
like image 36
qris Avatar answered Nov 04 '22 17:11

qris