diff --git a/flask/app.py b/flask/app.py index 97dc5bde..67383bbe 100644 --- a/flask/app.py +++ b/flask/app.py @@ -1492,6 +1492,7 @@ class Flask(_PackageBoundObject): if self.build_error_handler is None: exc_type, exc_value, tb = sys.exc_info() if exc_value is error: + # exception is current, raise in context of original traceback. raise exc_type, exc_value, tb else: raise error diff --git a/flask/helpers.py b/flask/helpers.py index 21b010b4..5560d38c 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -212,6 +212,40 @@ def url_for(endpoint, **values): For more information, head over to the :ref:`Quickstart `. + To integrate applications, :class:`Flask` has a hook to intercept URL build + errors through :attr:`Flask.build_error_handler`. The `url_for` function + results in a :exc:`~werkzeug.routing.BuildError` when the current app does + not have a URL for the given endpoint and values. When it does, the + :data:`~flask.current_app` calls its :attr:`~Flask.build_error_handler` if + it is not `None`, which can return a string to use as the result of + `url_for` (instead of `url_for`'s default to raise the + :exc:`~werkzeug.routing.BuildError` exception) or re-raise the exception. + An example:: + + def external_url_handler(error, endpoint, **values): + "Looks up an external URL when `url_for` cannot build a URL." + # This is an example of hooking the build_error_handler. + # Here, lookup_url is some utility function you've built + # which looks up the endpoint in some external URL registry. + url = lookup_url(endpoint, **values) + if url is None: + # External lookup did not have a URL. + # Re-raise the BuildError, in context of original traceback. + exc_type, exc_value, tb = sys.exc_info() + if exc_value is error: + raise exc_type, exc_value, tb + else: + raise error + # url_for will use this result, instead of raising BuildError. + return url + + app.build_error_handler = external_url_handler + + Here, `error` is the instance of :exc:`~werkzeug.routing.BuildError`, and + `endpoint` and `**values` are the arguments passed into `url_for`. Note + that this is for building URLs outside the current application, and not for + handling 404 NotFound errors. + .. versionadded:: 0.9 The `_anchor` and `_method` parameters were added.