diff --git a/services/web/server/src/simcore_service_webserver/exceptions_handlers.py b/services/web/server/src/simcore_service_webserver/exceptions_handlers.py index d0aefcf8e8aa..825f3ee23e5a 100644 --- a/services/web/server/src/simcore_service_webserver/exceptions_handlers.py +++ b/services/web/server/src/simcore_service_webserver/exceptions_handlers.py @@ -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 @@ -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, @@ -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 @@ -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 diff --git a/services/web/server/src/simcore_service_webserver/folders/_exceptions_handlers.py b/services/web/server/src/simcore_service_webserver/folders/_exceptions_handlers.py index 4e0f3958c237..4f83b5e1872c 100644 --- a/services/web/server/src/simcore_service_webserver/folders/_exceptions_handlers.py +++ b/services/web/server/src/simcore_service_webserver/folders/_exceptions_handlers.py @@ -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, ) diff --git a/services/web/server/src/simcore_service_webserver/projects/_trash_handlers.py b/services/web/server/src/simcore_service_webserver/projects/_trash_handlers.py index 2598a5cd4be7..066c3fe99d16 100644 --- a/services/web/server/src/simcore_service_webserver/projects/_trash_handlers.py +++ b/services/web/server/src/simcore_service_webserver/projects/_trash_handlers.py @@ -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 ) # diff --git a/services/web/server/tests/unit/isolated/test_exceptions_handlers.py b/services/web/server/tests/unit/isolated/test_exceptions_handlers.py index 4152ba51c286..27cde72283b5 100644 --- a/services/web/server/tests/unit/isolated/test_exceptions_handlers.py +++ b/services/web/server/tests/unit/isolated/test_exceptions_handlers.py @@ -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,