Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I debug a Flask application that has a custom exception handler?

I would like to implement an exception handler for my Flask application that displays a custom error page when an Exception is thrown. I can get this working easily with

@application.errorhandler(Exception)
def http_error_handler(error):
    return flask.render_template('error.html', error=error), 500

but this has the side effect of catching all exceptions before they hit the debugger (either the Werkzeug debugger or my IDE's) so that debugging is effectively disabled.

How can I implement a custom exception handler that still allows be to debug exceptions and errors? Is there a way to disable my custom handler when in debug mode?

like image 536
orome Avatar asked Jan 03 '15 22:01

orome


People also ask

How do you handle application errors in Flask?

Step 1 — Using The Flask Debugger. In this step, you'll create an application that has a few errors and run it without debug mode to see how the application responds. Then you'll run it with debug mode on and use the debugger to troubleshoot application errors.

How does Flask handle internal server error?

Make sure debug mode is off, then try again. Here is a comment directly from the code itself: Default exception handling that kicks in when an exception occurs that is not caught. In debug mode the exception will be re-raised immediately, otherwise it is logged and the handler for a 500 internal server error is used.


1 Answers

Werkzeug will generate a 500 exception when an uncaught exception propagates. Create an error handler for 500, not for Exception. The 500 handler is bypassed when debugging is enabled.

@app.errorhandler(500)
def handle_internal_error(e):
    return render_template('500.html', error=e), 500

The following is a full app that demonstrates that the error handler works for assert, raise, and abort.

from flask import Flask, abort

app = Flask(__name__)

@app.errorhandler(500)
def handle_internal_error(e):
    return 'got an error', 500

@app.route('/assert')
def from_assert():
    assert False

@app.route('/raise')
def from_raise():
    raise Exception()

@app.route('/abort')
def from_abort():
    abort(500)

app.run()

Going to all three urls (/assert, /raise, and /abort) will show the message "got an error". Running with app.run(debug=True) will only show the message for /abort since that is an "expected" response; the other two urls will show the debugger.

like image 184
davidism Avatar answered Oct 13 '22 06:10

davidism