flask: error_handler for blueprints

2020-02-05 06:22发布

问题:

Can error_handler be set for a blueprint?

@blueprint.errorhandler(404)
def page_not_found(error):
    return 'This page does not exist', 404

edit:

https://github.com/mitsuhiko/flask/blob/18413ed1bf08261acf6d40f8ba65a98ae586bb29/flask/blueprints.py

you can specify an app wide and a blueprint local error_handler

回答1:

You can use Blueprint.app_errorhandler method like this:

bp = Blueprint('errors', __name__)

@bp.app_errorhandler(404)
def handle_404(err):
    return render_template('404.html'), 404

@bp.app_errorhandler(500)
def handle_500(err):
    return render_template('500.html'), 500


回答2:

errorhandler is a method inherited from Flask, not Blueprint. If you are using Blueprint, the equivalent is app_errorhandler.

The documentation suggests the following approach:

def app_errorhandler(self, code):
        """Like :meth:`Flask.errorhandler` but for a blueprint.  This
        handler is used for all requests, even if outside of the blueprint.
        """

Therefore, this should work:

from flask import Blueprint, render_template

USER = Blueprint('user', __name__)

@USER.app_errorhandler(404)
def page_not_found(e):
    """ Return error 404 """
    return render_template('404.html'), 404

On the other hand, while the approach below did not raise any error for me, it didn't work:

from flask import Blueprint, render_template

USER = Blueprint('user', __name__)

@USER.errorhandler(404)
def page_not_found(e):
    """ Return error 404 """
    return render_template('404.html'), 404


回答3:

I too couldn't get the top rated answer to work, but here's a workaround.

You can use a catch-all at the end of your Blueprint, not sure how robust/recommended it is, but it does work. You could also add different error messages for different methods too.

@blueprint.route('/<path:path>')
def page_not_found(path):
    return "Custom failure message"


回答4:

add error handling at application level using the request proxy object:

from flask import request,jsonify

@app.errorhandler(404)
@app.errorhandler(405)
def _handle_api_error(ex):
if request.path.startswith('/api/'):
    return jsonify(ex)
else:
    return ex

flask Documentation



回答5:

Flask doesnt support blueprint level error handlers for 404 and 500 errors. A BluePrint is a leaky abstraction. Its better to use a new WSGI App for this, if you need separate error handlers, this makes more sense.

Also i would recommend not to use flask, it uses globals all over the places, which makes your code difficult to manage if it grows bigger.