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
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.
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.
Some of the common traceback errors are:IndexError. KeyError. TypeError. valueError.
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.
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
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, aTypeError
exception is raised indicating that this is an error (if running under IDLE, aQueue.Empty
exception is raised instead).Otherwise,
raise
evaluates the expressions to get three objects, usingNone
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 orNone
, aTypeError
exception is raised.The three-expression form of
raise
is useful to re-raise an exception transparently in anexcept
clause, butraise
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With