Improved interface for the URL build error handler

This commit is contained in:
Armin Ronacher 2012-05-08 11:56:11 +01:00
parent e78e2a1641
commit 2053d04db0
3 changed files with 29 additions and 25 deletions

View file

@ -19,7 +19,7 @@ from itertools import chain
from functools import update_wrapper
from werkzeug.datastructures import ImmutableDict
from werkzeug.routing import Map, Rule, RequestRedirect
from werkzeug.routing import Map, Rule, RequestRedirect, BuildError
from werkzeug.exceptions import HTTPException, InternalServerError, \
MethodNotAllowed, BadRequest
@ -341,16 +341,14 @@ class Flask(_PackageBoundObject):
#: decorator.
self.error_handler_spec = {None: self._error_handlers}
#: If not `None`, this function is called when :meth:`url_for` raises
#: :exc:`~werkzeug.routing.BuildError`, with the call signature::
#:
#: self.build_error_handler(error, endpoint, **values)
#:
#: Here, `error` is the instance of `BuildError`, and `endpoint` and
#: `**values` are the arguments passed into :meth:`url_for`.
#: A list of functions that are called when :meth:`url_for` raises a
#: :exc:`~werkzeug.routing.BuildError`. Each function registered here
#: is called with `error`, `endpoint` and `values`. If a function
#: returns `None` or raises a `BuildError` the next function is
#: tried.
#:
#: .. versionadded:: 0.9
self.build_error_handler = None
self.url_build_error_handlers = []
#: A dictionary with lists of functions that should be called at the
#: beginning of the request. The key of the dictionary is the name of
@ -1490,19 +1488,24 @@ class Flask(_PackageBoundObject):
for func in funcs:
func(endpoint, values)
def handle_build_error(self, error, endpoint, **values):
def handle_url_build_error(self, error, endpoint, values):
"""Handle :class:`~werkzeug.routing.BuildError` on :meth:`url_for`.
Calls :attr:`build_error_handler` if it is not `None`.
"""
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
return self.build_error_handler(error, endpoint, **values)
exc_type, exc_value, tb = sys.exc_info()
for handler in self.url_build_error_handlers:
try:
rv = handler(error, endpoint, values)
if rv is not None:
return rv
except BuildError, error:
pass
# At this point we want to reraise the exception. If the error is
# still the same one we can reraise it with the original traceback,
# otherwise we raise it from here.
if error is exc_value:
raise exc_type, exc_value, tb
raise error
def preprocess_request(self):
"""Called before the actual request dispatching and will