Reputation: 4894
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
Upvotes: 45
Views: 24210
Reputation: 1214
I combined previous excellent answers with the official docs from Flask, section 'Returning API Errors as JSON', in order to provide a more general approach.
Here is a working PoC that you can copy and paste on your registered blueprint API route handler (e.g. app/api/routes.py
):
from werkzeug.exceptions import HTTPException
@blueprint.app_errorhandler(HTTPException)
def handle_exception(e):
"""Return JSON instead of HTML for HTTP errors."""
# start with the correct headers and status code from the error
response = e.get_response()
# replace the body with JSON
response.data = json.dumps({
"code": e.code,
"name": e.name,
"description": e.description,
})
response.content_type = "application/json"
return response
Upvotes: 2
Reputation: 1431
Surprised others didn't mention miguelgrinberg's excellent tutorial.
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-vii-error-handling
I found the sentry framework for error handling (links below). Seems overly complex. not sure of the threshold where it becomes useful.
https://flask.palletsprojects.com/en/1.1.x/errorhandling/
https://docs.sentry.io/platforms/python/guides/flask/
Upvotes: 1
Reputation: 2150
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.
Upvotes: -10
Reputation: 351
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
Upvotes: 24
Reputation: 126
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
Upvotes: 3
Reputation: 100
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"
Upvotes: 2
Reputation: 3650
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
Upvotes: 50