In Flask, it is quite easy to register error handlers which re-direct to a custom error page like this
from flask import render_template @app.errorhandler(404) def page_not_found(e): return render_template('404.html'), 404
from werkzeug.exceptions import default_exceptions def init_app(app): ''' Function to register error_handler in app ''' for exception in default_exceptions: app.register_error_handler(exception, error_handler) app.register_error_handler(Exception, error_handler)
def error_handler(error): ''' Catches all errors in the default_exceptions list ''' msg = "Request resulted in {}".format(error) if current_user.is_authenticated: current_app.logger.error(msg, exc_info=error) else: current_app.logger.warning(msg, exc_info=error) if isinstance(error, HTTPException): description = error.get_description(request.environ) code = error.code name = error.name else: description = ("We encountered an error " "while trying to fulfill your request") code = 500 name = 'Internal Server Error' templates_to_try = ['errors/error{}.html'.format(code), 'errors/generic_error.html'] return render_template(templates_to_try, code=code, name=Markup(name), description=Markup(description), error=error), code
In the next step, the handler extracts all information it can get from the error message and then renders a template. The render_template function will go through the templates_to_try list until it finds an existing template, so this way you can register custom pages for certain errors but if a custom error does not exist, it will just render the general error page, which in my case looks like this
{% extends "master.html" %} {% block title %}Error{% endblock %} {% block description %} <meta name="description" content="Error message."> {% endblock %} {% block body %} <div id="navbar_wrapper"> <div id="site_content"> <div class="container"> <div class="col-xs-12 col-sm-9 col-md-10 col-lg-10"> <br> <h1>{{ code }}:{{ name }}</h1> <p>{{description}}</p> <p>The administrator has been notified. Sorry for the inconvenience!</p>
<button class="btn btn-primary" onclick="history.back(-1)">Go Back</button>
</div> </div> </div> </div> {% endblock %}
I put the entire example on Github. Let me know if you have any comments or questions.
cheers
Florian
No comments:
Post a Comment