Merge pull request #379 from youknowone/exception

Let exception handler handle inherited exceptions
This commit is contained in:
Eli Uriegas 2017-02-08 19:20:42 -06:00 committed by GitHub
commit a5a7490bca
2 changed files with 33 additions and 4 deletions

View File

@ -143,9 +143,12 @@ class PayloadTooLarge(SanicException):
class Handler: class Handler:
handlers = None handlers = None
cached_handlers = None
_missing = object()
def __init__(self): def __init__(self):
self.handlers = {} self.handlers = []
self.cached_handlers = {}
self.debug = False self.debug = False
def _render_traceback_html(self, exception, request): def _render_traceback_html(self, exception, request):
@ -164,7 +167,18 @@ class Handler:
uri=request.url) uri=request.url)
def add(self, exception, handler): def add(self, exception, handler):
self.handlers[exception] = handler self.handlers.append((exception, handler))
def lookup(self, exception):
handler = self.cached_handlers.get(exception, self._missing)
if handler is self._missing:
for exception_class, handler in self.handlers:
if isinstance(exception, exception_class):
self.cached_handlers[type(exception)] = handler
return handler
self.cached_handlers[type(exception)] = None
handler = None
return handler
def response(self, request, exception): def response(self, request, exception):
""" """
@ -174,9 +188,12 @@ class Handler:
:param exception: Exception to handle :param exception: Exception to handle
:return: Response object :return: Response object
""" """
handler = self.handlers.get(type(exception), self.default) handler = self.lookup(exception)
try: try:
response = handler(request=request, exception=exception) response = handler and handler(
request=request, exception=exception)
if response is None:
response = self.default(request=request, exception=exception)
except: except:
log.error(format_exc()) log.error(format_exc())
if self.debug: if self.debug:

View File

@ -28,6 +28,13 @@ def handler_4(request):
return text(foo) return text(foo)
@exception_handler_app.route('/5')
def handler_5(request):
class CustomServerError(ServerError):
pass
raise CustomServerError('Custom server error')
@exception_handler_app.exception(NotFound, ServerError) @exception_handler_app.exception(NotFound, ServerError)
def handler_exception(request, exception): def handler_exception(request, exception):
return text("OK") return text("OK")
@ -71,3 +78,8 @@ def test_html_traceback_output_in_debug_mode():
assert ( assert (
"NameError: name 'bar' " "NameError: name 'bar' "
"is not defined while handling uri /4") == summary_text "is not defined while handling uri /4") == summary_text
def test_inherited_exception_handler():
request, response = sanic_endpoint_test(exception_handler_app, uri='/5')
assert response.status == 200