|
|
|
@ -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 |
|
|
|
|