Perhaps I am not seeing something in the documentation.
I would like to not just handle some http errors, but all exceptions. The reason - I would like to log them using my own custom logic (sounds like reinventing the wheel, but I need full control over logging. I would like to not bring the server to its knees upon an exception, but bomb only that particular request.
This is how I launch Flask now. Here app.run
starts the server. How can I instruct it to call my exception handler method whenever an exception occurs?
def main():
args = parse_args()
app.config['PROPAGATE_EXCEPTIONS'] = True
flask_options = {'port' : args.port}
if args.host == 'public':
flask_options['host'] = '0.0.0.0'
app.run(**flask_options)
if __name__ == '__main__':
_sys.exit(main())
Old question, but for anyone reading in 2021:
For all exceptions that aren't explicitly defined a 500 code can be returned.
The structure of the function is from Flask cookiecutter, though the pattern had a Jinja template for every error.
I haven't had luck catching all exceptions automatically, but I found this to be a lot DRYer then having an individual page for each individual exception.
"""
app.exceptions
==============
(python3)
"""
# app/exceptions.py
from typing import Tuple
from flask import Flask, render_template
from werkzeug.exceptions import HTTPException
EXCEPTIONS = {
400: "Bad Request",
401: "Unauthorized",
403: "Forbidden",
404: "Not Found",
405: "Method Not Allowed",
500: "Internal Server Error",
}
# general function structure: https://github.com/cookiecutter-flask/cookiecutter-flask
def init_app(app: Flask) -> None:
"""Register error handlers."""
def render_error(error: HTTPException) -> Tuple[str, int]:
"""Render error template.
If a HTTPException, pull the ``code`` attribute; default to 500.
:param error: Exception to catch and render page for.
:return: Tuple consisting of rendered template and error code.
"""
app.logger.error(error.description)
error_code = getattr(error, "code", 500)
return (
render_template(
"exception.html",
error_code=error_code,
exception=EXCEPTIONS[error_code],
),
error_code,
)
for errcode in [400, 401, 403, 404, 405, 500]:
app.errorhandler(errcode)(render_error)
{# app/templates/exception.html #}
{% extends "base.html" %}
{# page header and browser tab #}
{% block page_name %}{{ error_code }} {{ exception }}{% endblock %}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With