Python (and ipython) has very powerful post-mortem debugging capabilities, allowing variable inspection and command execution at each scope in the traceback. The up/down debugger commands allow changing frame for the stack trace of the final exception, but what about the __cause__ of that exception, as defined by the raise ... from ... syntax? Python 3.7.6 (default, Jan 8 2020, 13:42:34) Type 'copyright', 'credits' or 'license' for more information IPython 7.11.1 -- An enhanced Interactive Python. Type '?' for help. In [1]: def foo(): ...: bab = 42 ...: raise TypeError ...: In [2]: try: ...: foo() ...: except TypeError as err: ...: barz = 5 ...: raise ValueError from err ...: --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-2-dd046d7cece0> in <module> 1 try: ----> 2 foo() 3 except TypeError as err: <ipython-input-1-da9a05838c59> in foo() 2 bab = 42 ----> 3 raise TypeError 4 TypeError: The above exception was the direct cause of the following exception: ValueError Traceback (most recent call last) <ipython-input-2-dd046d7cece0> in <module> 3 except TypeError as err: 4 barz = 5 ----> 5 raise ValueError from err 6 ValueError: In [3]: %debug > <ipython-input-2-dd046d7cece0>(5)<module>() 2 foo() 3 except TypeError as err: 4 barz = 5 ----> 5 raise ValueError from err 6 ipdb> barz 5 ipdb> bab *** NameError: name 'bab' is not defined ipdb> down *** Newest frame ipdb> up *** Oldest frame Is there a way to access bab from the debugger? EDIT: I realized post-mortem debugging isn't just a feature of ipython and ipdb, it's actually part of vanilla pdb. The above can also be reproduced by putting the code into a script testerr.py and running python -m pdb testerr.py and running continue. After the error, it says Uncaught exception. Entering post mortem debugging Running 'cont' or 'step' will restart the program and gives a debugger at the same spot. Continue reading...