Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Exception Propagation

I'm building a tool where as exceptions propagate upwards, new data about the context of the exception gets added to the exception. The issue is, by the time the exception gets to the top level, all of the extra context data is there, but only the very latest stack trace is shown. Is there an easy way to have an exception show the original stack trace in which it was thrown instead of the last stack trace, or should I do something like grab the original stack trace the first time that the exception propagates?

For example, the following code:

def a():
    return UNBOUND
def b():
    try:
        a()
    except Exception as e:
        raise e
b()

yields the following exception:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    b()
  File "test.py", line 7, in b
    raise e
NameError: global name 'UNBOUND' is not defined

where, ideally, I'd like to somehow show the user this:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
  File "test.py", line 2, in a
    return UNBOUND
NameError: global name 'UNBOUND' is not defined

As that points the user to the line that the error originally occurred on.

like image 692
So8res Avatar asked Dec 11 '09 23:12

So8res


People also ask

What is exception Propagation in Python?

When an exception is raised, the exception-propagation mechanism takes control. The normal control flow of the program stops, and Python looks for a suitable exception handler. Python's try statement establishes exception handlers via its except clauses.

What is propagation of exception?

when an exception happens, Propagation is a process in which the exception is being dropped from to the top to the bottom of the stack. If not caught once, the exception again drops down to the previous method and so on until it gets caught or until it reach the very bottom of the call stack.

What exceptions are automatically propagated?

unchecked exceptions are automatically propagated in java.

Can you have multiple excepts for one try in Python?

According to the Python Documentation: A try statement may have more than one except clause, to specify handlers for different exceptions. At most one handler will be executed. In this example, we have two except clauses.


1 Answers

Python exceptions are a bit like java, there is a way to cause the exception to be rethrown without truncating the stack.

Just use raise without an argument. The result it:

Traceback (most recent call last):
  File "./exc.py", line 11, in <module>
    b()
  File "./exc.py", line 7, in b
    a()
  File "./exc.py", line 4, in a
    return UNBOUND
NameError: global name 'UNBOUND' is not defined

You can modify some things about the e object, even if you just raise without that argument - for example:

e.args = ("hi!",)
raise 

will actually change the exception message. You can probably change the other options too this way - without destroying the stack.

like image 50
viraptor Avatar answered Oct 22 '22 23:10

viraptor