Closed davidism closed 5 months ago
For example, pip install pudb
, then run a Flask application with PYTHONBREAKPOINT=pudb.set_trace flask run --debug
. On an unhandled exception, the browser displays a standard 500 error page, and the nice PUDB UI is displayed in the terminal. PyCharm sets this for you, so if you start a Flask app with the debug button, an unhandled exception will activate the debug panel frame inspector.
I deliberately named this WSGIMiddleware
, since I think an ASGIMiddleware
could easily be written as well, I just don't know quite enough about how ASGI handles errors to do that.
One thing I failed to account for is that breakpoint()
doesn't deal with post-mortem debugging. Calling breakpoint()
stops where it's called in the except
block, which is after the function that raised it has exited (due to raising an exception). We want to debug the traceback that we caught, not the current state. Most debuggers do have a separate post_mortem()
call instead of set_trace()
, but it's not guaranteed, and we'd need some way to detect the debugger and then find its post mortem call instead.
The interactive debugger is a constant source of (usually invalid) security reports. Nowadays, there are a lot of nice Python debuggers besides the built-in
pdb
. Python has a built-inbreakpoint()
function which will start the user's preferred debugger. For example, pudb, ipdb, pdbpp, or IDE debuggers such as PyCharm and VSCode. This middleware catches unhandled exceptions, finishes the response, then callsbreakpoint()
to allow the user to inspect the stack. This provides exactly as much information as the interactive debugger, but without the huge complexity of storing frames, threads, contexts, etc or serving a remote Python interpreter UI.