Skip to content

Commit

Permalink
renames
Browse files Browse the repository at this point in the history
  • Loading branch information
pcrespov committed Nov 26, 2024
1 parent 6f27e33 commit f8e744c
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .exceptions_handlers_base import async_try_except_decorator
from .exceptions_handlers_base import exception_handling_decorator
from .exceptions_handlers_http_error_map import (
ExceptionToHttpErrorMap,
HttpErrorInfo,
Expand All @@ -8,7 +8,7 @@
__all__: tuple[str, ...] = (
"ExceptionToHttpErrorMap",
"HttpErrorInfo",
"async_try_except_decorator",
"exception_handling_decorator",
"to_exceptions_handlers_map",
)

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

from aiohttp import web
from servicelib.aiohttp.typing_extension import Handler as WebHandler
from servicelib.aiohttp.typing_extension import Middleware as WebMiddleware

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -46,10 +47,7 @@ def _sort_exceptions_by_specificity(
ExceptionHandlersMap: TypeAlias = dict[type[BaseException], AiohttpExceptionHandler]


class AsyncDynamicTryExceptContext(AbstractAsyncContextManager):
"""Context manager to handle exceptions if they match any in the
exception_handlers_map"""

class ExceptionHandlingContextManager(AbstractAsyncContextManager):
def __init__(
self,
exception_handlers_map: ExceptionHandlersMap,
Expand Down Expand Up @@ -105,13 +103,15 @@ def get_response(self):
return self._response


def async_try_except_decorator(
def exception_handling_decorator(
exception_handlers_map: dict[type[BaseException], AiohttpExceptionHandler]
):
def _decorator(handler: WebHandler):
@functools.wraps(handler)
async def _wrapper(request: web.Request) -> web.StreamResponse:
cm = AsyncDynamicTryExceptContext(exception_handlers_map, request=request)
cm = ExceptionHandlingContextManager(
exception_handlers_map, request=request
)
async with cm:
return await handler(request)

Expand All @@ -123,3 +123,17 @@ async def _wrapper(request: web.Request) -> web.StreamResponse:
return _wrapper

return _decorator


def exception_handling_middleware(
exception_handlers_map: dict[type[BaseException], AiohttpExceptionHandler]
) -> WebMiddleware:
_handle_excs = exception_handling_decorator(
exception_handlers_map=exception_handlers_map
)

@web.middleware
async def middleware_handler(request: web.Request, handler: WebHandler):
return await _handle_excs(handler)(request)

return middleware_handler
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,22 @@
from models_library.rest_error import ErrorGet
from servicelib.aiohttp.web_exceptions_extension import get_all_aiohttp_http_exceptions
from servicelib.logging_errors import create_troubleshotting_log_kwargs
from servicelib.status_codes_utils import is_5xx_server_error
from servicelib.status_codes_utils import is_5xx_server_error, is_error

from .exceptions_handlers_base import AiohttpExceptionHandler, ExceptionHandlersMap

_logger = logging.getLogger(__name__)


_STATUS_CODE_TO_HTTP_ERRORS: dict[
int, type[web.HTTPException]
] = get_all_aiohttp_http_exceptions(web.HTTPError)
def create_error_response(error: ErrorGet, status_code: int) -> web.Response:
assert is_error(status_code), f"{status_code=} must be an error [{error=}]" # nosec

return web.json_response(
data={"error": error.model_dump(exclude_unset=True, mode="json")},
dumps=json_dumps,
reason=error.msg,
status=status_code,
)


class _DefaultDict(dict):
Expand All @@ -35,7 +41,7 @@ class HttpErrorInfo(NamedTuple):
ExceptionToHttpErrorMap: TypeAlias = dict[type[BaseException], HttpErrorInfo]


def create_exception_handler_from_http_error(
def create_exception_handler_from_http_info(
status_code: int,
msg_template: str,
) -> AiohttpExceptionHandler:
Expand All @@ -56,10 +62,13 @@ def create_exception_handler_from_http_error(
Returns:
A web api exception handler
"""
assert is_error( # nosec
status_code
), f"{status_code=} must be an error [{msg_template=}]"

async def _exception_handler(
request: web.Request,
exception: BaseException,
exception: BaseException, # TODO: for different type of exceptions e.g HTTPError
) -> web.Response:

# safe formatting, i.e. does not raise
Expand All @@ -86,12 +95,7 @@ async def _exception_handler(
)
error = ErrorGet(msg=user_msg, support_id=IDStr(oec))

return web.json_response(
data={"error": error.model_dump(exclude_unset=True, mode="json")},
dumps=json_dumps,
reason=user_msg,
status=status_code,
)
return create_error_response(error, status_code=status_code)

return _exception_handler

Expand All @@ -101,10 +105,28 @@ def to_exceptions_handlers_map(
) -> ExceptionHandlersMap:
"""Converts { exc_type: (status, msg), ... } -> { exc_type: callable, ... }"""
exc_handlers_map: ExceptionHandlersMap = {
exc_type: create_exception_handler_from_http_error(
exc_type: create_exception_handler_from_http_info(
status_code=info.status_code, msg_template=info.msg_template
)
for exc_type, info in exc_to_http_error_map.items()
}

return exc_handlers_map


_STATUS_CODE_TO_HTTP_ERRORS: dict[
int, type[web.HTTPError]
] = get_all_aiohttp_http_exceptions(web.HTTPError)


def create_http_error_exception_handlers_map():
"""
Creates handles for all web.HTTPError
"""
exc_handlers_map: ExceptionHandlersMap = {
exc_type: create_exception_handler_from_http_info(
status_code=code, msg_template="{reason}"
)
for code, exc_type in _STATUS_CODE_TO_HTTP_ERRORS.items()
}
return exc_handlers_map
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from ..exceptions_handlers import (
ExceptionToHttpErrorMap,
HttpErrorInfo,
async_try_except_decorator,
exception_handling_decorator,
to_exceptions_handlers_map,
)
from ..projects.exceptions import ProjectRunningConflictError, ProjectStoppingError
Expand Down Expand Up @@ -65,7 +65,7 @@
}


handle_plugin_requests_exceptions = async_try_except_decorator(
handle_plugin_requests_exceptions = exception_handling_decorator(
to_exceptions_handlers_map(_TO_HTTP_ERROR_MAP)
)
# this is one decorator with a single exception handler
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from ..exceptions_handlers import (
ExceptionToHttpErrorMap,
HttpErrorInfo,
async_try_except_decorator,
exception_handling_decorator,
to_exceptions_handlers_map,
)
from ..login.decorators import get_user_id, login_required
Expand Down Expand Up @@ -42,7 +42,7 @@
}


_handle_exceptions = async_try_except_decorator(
_handle_exceptions = exception_handling_decorator(
to_exceptions_handlers_map(_TO_HTTP_ERROR_MAP)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from ..exceptions_handlers import (
ExceptionToHttpErrorMap,
HttpErrorInfo,
async_try_except_decorator,
exception_handling_decorator,
to_exceptions_handlers_map,
)
from ..projects.exceptions import ProjectRunningConflictError, ProjectStoppingError
Expand Down Expand Up @@ -43,6 +43,6 @@
}


handle_plugin_requests_exceptions = async_try_except_decorator(
handle_plugin_requests_exceptions = exception_handling_decorator(
to_exceptions_handlers_map(_TO_HTTP_ERROR_MAP)
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
from simcore_service_webserver.errors import WebServerBaseError
from simcore_service_webserver.exceptions_handlers_base import (
AiohttpExceptionHandler,
AsyncDynamicTryExceptContext,
ExceptionHandlingContextManager,
_sort_exceptions_by_specificity,
async_try_except_decorator,
exception_handling_decorator,
)

# Some custom errors in my service
Expand Down Expand Up @@ -88,7 +88,9 @@ async def _concrete_exc_handler(request, exception):
}

# handles any BaseError returning a response
cm = AsyncDynamicTryExceptContext(exception_handlers_map, request=expected_request)
cm = ExceptionHandlingContextManager(
exception_handlers_map, request=expected_request
)
async with cm:
raise OneError
assert cm.get_response() == expected_response
Expand All @@ -115,7 +117,7 @@ async def _suppress_all(request: web.Request, exception):
assert request == expected_request
return expected_response

@async_try_except_decorator({BaseError: _suppress_all})
@exception_handling_decorator({BaseError: _suppress_all})
async def _rest_handler(request: web.Request) -> web.Response:
raise expected_exception

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
from servicelib.mimetype_constants import MIMETYPE_APPLICATION_JSON
from simcore_service_webserver.errors import WebServerBaseError
from simcore_service_webserver.exceptions_handlers_base import (
AsyncDynamicTryExceptContext,
async_try_except_decorator,
ExceptionHandlingContextManager,
exception_handling_decorator,
)
from simcore_service_webserver.exceptions_handlers_http_error_map import (
ExceptionToHttpErrorMap,
HttpErrorInfo,
create_exception_handler_from_http_error,
create_exception_handler_from_http_info,
to_exceptions_handlers_map,
)

Expand All @@ -48,7 +48,7 @@ def fake_request() -> web.Request:
async def test_factory__create_exception_handler_from_http_error(
fake_request: web.Request,
):
one_error_to_404 = create_exception_handler_from_http_error(
one_error_to_404 = create_exception_handler_from_http_info(
status_code=status.HTTP_404_NOT_FOUND,
msg_template="one error message for the user: {code} {value}",
)
Expand All @@ -70,7 +70,7 @@ async def test_handling_different_exceptions_with_context(
OneError: HttpErrorInfo(status.HTTP_400_BAD_REQUEST, "Error {code} to 400"),
OtherError: HttpErrorInfo(status.HTTP_500_INTERNAL_SERVER_ERROR, "{code}"),
}
cm = AsyncDynamicTryExceptContext(
cm = ExceptionHandlingContextManager(
to_exceptions_handlers_map(exc_to_http_error_map), request=fake_request
)

Expand Down Expand Up @@ -118,7 +118,7 @@ async def test_handling_different_exceptions_with_decorator(
OneError: HttpErrorInfo(status.HTTP_503_SERVICE_UNAVAILABLE, "{code}"),
}

exc_handling_decorator = async_try_except_decorator(
exc_handling_decorator = exception_handling_decorator(
to_exceptions_handlers_map(exc_to_http_error_map)
)

Expand Down

0 comments on commit f8e744c

Please sign in to comment.