How to re-raise an exception in nested try/except blocks?
I know that if I want to re-raise an exception, I simple use
raise without arguments in the respective
except block. But given a nested expression like
try: something() except SomeError as e: try: plan_B() except AlsoFailsError: raise e # I'd like to raise the SomeError as if plan_B() # didn't raise the AlsoFailsError
how can I re-raise the
SomeError without breaking the stack trace?
raise alone would in this case re-raise the more recent
AlsoFailsError. Or how could I refactor my code to avoid this issue?
You can store the exception type, value, and traceback in local variables and use the three-argument form of
try: something() except SomeError: t, v, tb = sys.exc_info() try: plan_B() except AlsoFailsError: raise t, v, tb
In Python 3 the traceback is stored in the exception, so
raise e will do the (mostly) right thing:
try: something() except SomeError as e: try: plan_B() except AlsoFailsError: raise e
The only problem with the above is that it will produce a slightly misleading traceback that tells you that
SomeError occurred while handling
AlsoFailsError (because of
raise e inside
Except AlsoFailsError), where in fact the almost exact opposite occurred - we handled
AlsoFailsError while trying to recover from
SomeError. To disable this behavior and get a traceback that never mentions
raise e with
raise e from None.