From 9d3c4bbb8c180cc3f42edacc41f74ca327af9805 Mon Sep 17 00:00:00 2001 From: Phil Schaf Date: Sat, 11 Apr 2015 16:57:17 +0200 Subject: [PATCH] Added docs for the error handler rework --- docs/errorhandling.rst | 57 ++++++++++++++++++++++++++++++++++++++++-- docs/quickstart.rst | 2 ++ docs/upgrading.rst | 15 +++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/docs/errorhandling.rst b/docs/errorhandling.rst index aa1d34f7..4bbf73c3 100644 --- a/docs/errorhandling.rst +++ b/docs/errorhandling.rst @@ -1,7 +1,7 @@ .. _application-errors: -Logging Application Errors -========================== +Application Errors +================== .. versionadded:: 0.3 @@ -28,6 +28,59 @@ exception to the :attr:`~flask.Flask.logger`. But there is more you can do, and we will cover some better setups to deal with errors. +.. _error-handlers: + +Error handlers +-------------- + +.. versionadded:: 1.0 + +Some errors are unavoidable because not only you make them. Users might +enter a wrong password or do something different in a way that you just +cannot allow. Or a third party service that your site relies on is +unreachable while an user tries to do something with it. + +In those cases you might want to show error pages to the user in response. +This can be done by registering error handlers. + +Error handlers are normal :ref:`views` but instead of being registered for +routes they are registered exceptions that are rised while trying to do +something else. + +Registering +``````````` + +Register error handlers using :meth:`~flask.Flask.errorhandler` or +:meth:`~flask.Flask.register_error_handler`:: + + @app.errorhandler(werkzeug.exceptions.BadRequest) + def handle_bad_request(e): + return 'bad request!' + + app.register_error_handler(400, lambda e: 'bad request!') + +Those two ways are equivalent, but the first one is more clear and leaves +you with a function to call on your whim (and in tests). Note that +:exc:`werkzeug.exceptions.HTTPException` subclasses like +:exc:`~werkzeug.exceptions.BadRequest` from the example and their HTTP codes +are interchangable when handed to the registration methods or decorator +(``BadRequest.code == 400``). + +You are however not limited to a :exc:`~werkzeug.exceptions.HTTPException` +or its code but can register a handler for every exception class you like. + +Handling +```````` + +Once an exception instance is raised, its class hierarchy is traversed, +and searched for in the exception classes for which handlers are registered. +The most specific handler is selected. + +E.g. if a instance of :exc:`ConnectionRefusedError` is raised, and a handler +is registered for :exc:`ConnectionError` and :exc:`ConnectionRefusedError`, +the more specific :exc:`ConnectionRefusedError` handler is called on the +exception instance, and its response is shown to the user. + Error Mails ----------- diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 4906d025..b28c10d6 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -701,6 +701,8 @@ Note the ``404`` after the :func:`~flask.render_template` call. This tells Flask that the status code of that page should be 404 which means not found. By default 200 is assumed which translates to: all went well. +See :ref:`error-handlers` for more details. + .. _about-responses: About Responses diff --git a/docs/upgrading.rst b/docs/upgrading.rst index 4f00aa5e..d504da44 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -29,6 +29,21 @@ applications. Instead the new ``LOGGER_HANDLER_POLICY`` configuration can be used to disable the default log handlers and custom log handlers can be set up. +The behavior of error handlers was changed. +The precedence of handlers used to be based on the decoration/call order of +:meth:`~flask.Flask.errorhandler` and +:meth:`~flask.Flask.register_error_handler`, respectively. +Now the inheritance hierarchy takes precedence and handlers for more +specific exception classes are executed instead of more general ones. +See :ref:`error-handlers` for specifics. + +.. note:: + + There used to be a logic error allowing you to register handlers + only for exception *instances*. This was unintended and plain wrong, + and therefore was replaced with the intended behavior of registering + handlers only using exception classes and HTTP error codes. + .. _upgrading-to-010: Version 0.10