Skip to content

Commit

Permalink
improves error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
pcrespov committed Nov 6, 2024
1 parent e84b6d2 commit 110e1eb
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import functools
import logging
from typing import NamedTuple, TypeAlias
from typing import Iterable, NamedTuple, TypeAlias

from aiohttp import web
from servicelib.aiohttp.typing_extension import Handler
Expand All @@ -25,7 +25,7 @@ def __missing__(self, key):


def _sort_exceptions_by_specificity(
exceptions: list[type[BaseException]], *, concrete_first: bool = True
exceptions: Iterable[type[BaseException]], *, concrete_first: bool = True
) -> list[type[BaseException]]:
return sorted(
exceptions,
Expand All @@ -35,22 +35,27 @@ def _sort_exceptions_by_specificity(


def create_exception_handlers_decorator(
exception_catch: type[BaseException] | tuple[type[BaseException], ...],
exceptions_catch: type[BaseException] | tuple[type[BaseException], ...],
exc_to_status_map: ExceptionToHttpErrorMap,
):

included: list[type[BaseException]] = _sort_exceptions_by_specificity(
list(exc_to_status_map.keys())
mapped_classes: tuple[type[BaseException], ...] = tuple(
_sort_exceptions_by_specificity(exc_to_status_map.keys())
)

assert all( # nosec
issubclass(cls, exceptions_catch) for cls in mapped_classes
), f"Every {mapped_classes=} must inherit by one or more of {exceptions_catch=}"

def _decorator(handler: Handler):
@functools.wraps(handler)
async def _wrapper(request: web.Request) -> web.StreamResponse:
try:
return await handler(request)

except exception_catch as exc:
if exc_cls := next((_ for _ in included if isinstance(exc, _)), None):
except exceptions_catch as exc:
if exc_cls := next(
(cls for cls in mapped_classes if isinstance(exc, cls)), None
):
http_error_info = exc_to_status_map[exc_cls]

# safe formatting, i.e. does not raise
Expand All @@ -77,7 +82,7 @@ async def _wrapper(request: web.Request) -> web.StreamResponse:
)
)
raise http_error_cls(reason=user_msg) from exc
raise
raise # reraise

return _wrapper

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@


handle_plugin_requests_exceptions = create_exception_handlers_decorator(
exception_catch=(BaseProjectError, FoldersValueError, WorkspacesValueError),
exceptions_catch=(BaseProjectError, FoldersValueError, WorkspacesValueError),
exc_to_status_map=_TO_HTTP_ERROR_MAP,
)
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@


_handle_exceptions = create_exception_handlers_decorator(
exception_catch=ProjectTrashError, exc_to_status_map=_TO_HTTP_ERROR_MAP
exceptions_catch=ProjectTrashError, exc_to_status_map=_TO_HTTP_ERROR_MAP
)

#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ async def test_exception_handlers_decorator(
):

_handle_exceptions = create_exception_handlers_decorator(
exception_catch=BasePluginError,
exceptions_catch=BasePluginError,
exc_to_status_map={
OneError: HttpErrorInfo(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
Expand Down

0 comments on commit 110e1eb

Please sign in to comment.