From 80fca9aef7ec0009f24f2257d7d75ef726fcd77a Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Mon, 21 Jun 2021 14:14:07 +0300 Subject: [PATCH] Better exception handling (#2128) * WIP for better exception handling * Note about removal * resolve conditional to reduce lookups * Cleanup logic --- sanic/handlers.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/sanic/handlers.py b/sanic/handlers.py index dc6c7bea..dd1fbac1 100644 --- a/sanic/handlers.py +++ b/sanic/handlers.py @@ -25,7 +25,6 @@ class ErrorHandler: handlers = None cached_handlers = None - _missing = object() def __init__(self): self.handlers = [] @@ -45,7 +44,9 @@ class ErrorHandler: :return: None """ + # self.handlers to be deprecated and removed in version 21.12 self.handlers.append((exception, handler)) + self.cached_handlers[exception] = handler def lookup(self, exception): """ @@ -61,14 +62,19 @@ class ErrorHandler: :return: Registered function if found ``None`` otherwise """ - handler = self.cached_handlers.get(type(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 + exception_class = type(exception) + if exception_class in self.cached_handlers: + return self.cached_handlers[exception_class] + + for ancestor in type.mro(exception_class): + if ancestor in self.cached_handlers: + handler = self.cached_handlers[ancestor] + self.cached_handlers[exception_class] = handler + return handler + if ancestor is BaseException: + break + self.cached_handlers[exception_class] = None + handler = None return handler def response(self, request, exception):