forked from Github-Mirrors/canaille
feat: generic blueprint HTTP 404 error handler
This allows blueprint to handle 404 errors. This is not supported directly in Flask. https://flask.palletsprojects.com/en/stable/errorhandling/#handling However, the blueprint cannot handle 404 routing errors because the 404 occurs at the routing level before the blueprint can be determined.
This commit is contained in:
parent
e031b74684
commit
309511e91c
2 changed files with 28 additions and 9 deletions
|
@ -5,7 +5,9 @@ from urllib.parse import urlunsplit
|
||||||
|
|
||||||
from flask import abort
|
from flask import abort
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
from flask import make_response
|
||||||
from flask import request
|
from flask import request
|
||||||
|
from werkzeug.exceptions import HTTPException
|
||||||
from werkzeug.routing import BaseConverter
|
from werkzeug.routing import BaseConverter
|
||||||
|
|
||||||
from canaille.app.i18n import gettext as _
|
from canaille.app.i18n import gettext as _
|
||||||
|
@ -107,3 +109,19 @@ def model_converter(model):
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
return ModelConverter
|
return ModelConverter
|
||||||
|
|
||||||
|
|
||||||
|
def redirect_to_bp_handlers(app, error):
|
||||||
|
"""Find and execute blueprint handlers matching an error.
|
||||||
|
|
||||||
|
There is currently no way to make 404 handling generic:
|
||||||
|
https://flask.palletsprojects.com/en/stable/errorhandling/#handling
|
||||||
|
However, the blueprint cannot handle 404 routing errors because the
|
||||||
|
404 occurs at the routing level before the blueprint can be determined.
|
||||||
|
"""
|
||||||
|
for bp in app.blueprints.values():
|
||||||
|
if bp.url_prefix and request.path.startswith(bp.url_prefix):
|
||||||
|
for type_, handler in bp.error_handler_spec[None][None].items():
|
||||||
|
if type_ in (error.code, HTTPException): # pragma: no branch
|
||||||
|
return make_response(handler(error))
|
||||||
|
return None
|
||||||
|
|
|
@ -40,15 +40,11 @@ if flask_themer:
|
||||||
|
|
||||||
@app.errorhandler(404)
|
@app.errorhandler(404)
|
||||||
def page_not_found(error):
|
def page_not_found(error):
|
||||||
# There is currently no way to make 404 handling generic
|
from canaille.app.flask import redirect_to_bp_handlers
|
||||||
# https://flask.palletsprojects.com/en/stable/errorhandling/#handling
|
|
||||||
# However, the blueprint cannot handle 404 routing errors because the
|
|
||||||
# 404 occurs at the routing level before the blueprint can be determined.
|
|
||||||
if flask.request.path.startswith("/scim/"):
|
|
||||||
from canaille.scim.endpoints import http_error_handler
|
|
||||||
|
|
||||||
return http_error_handler(error)
|
return redirect_to_bp_handlers(app, error) or render_template(
|
||||||
return render_template("error.html", description=error, error_code=404), 404
|
"error.html", description=error, error_code=404
|
||||||
|
), 404
|
||||||
|
|
||||||
@app.errorhandler(500)
|
@app.errorhandler(500)
|
||||||
def server_error(error): # pragma: no cover
|
def server_error(error): # pragma: no cover
|
||||||
|
@ -58,4 +54,9 @@ else: # pragma: no cover
|
||||||
render_template = flask.render_template
|
render_template = flask.render_template
|
||||||
|
|
||||||
def setup_themer(app):
|
def setup_themer(app):
|
||||||
return
|
@app.errorhandler(404)
|
||||||
|
def page_not_found(error):
|
||||||
|
from canaille.app.flask import redirect_to_bp_handlers
|
||||||
|
|
||||||
|
if not redirect_to_bp_handlers(app, error):
|
||||||
|
raise error
|
||||||
|
|
Loading…
Reference in a new issue