88from typing import Any
99
1010from aiohttp import web
11+ from aiohttp .web_exceptions import HTTPError
1112from aiohttp .web_request import Request
1213from aiohttp .web_response import StreamResponse
1314from common_library .error_codes import create_error_code
1819from ..mimetype_constants import MIMETYPE_APPLICATION_JSON
1920from ..rest_responses import is_enveloped_from_map , is_enveloped_from_text
2021from ..utils import is_production_environ
22+ from . import status
2123from .rest_responses import (
2224 create_data_response ,
2325 create_http_error ,
2628)
2729from .rest_utils import EnvelopeFactory
2830from .typing_extension import Handler , Middleware
31+ from .web_exceptions_extension import get_http_error_class_or_none
2932
3033DEFAULT_API_VERSION = "v0"
3134_FMSG_INTERNAL_ERROR_USER_FRIENDLY = (
@@ -79,6 +82,7 @@ def _handle_http_error(
7982 request : web .BaseRequest , exception : web .HTTPError
8083) -> web .HTTPError :
8184 """Handle standard HTTP errors by ensuring they're properly formatted."""
85+ assert request # nosec
8286 exception .content_type = MIMETYPE_APPLICATION_JSON
8387 if exception .reason :
8488 exception .set_status (
@@ -103,8 +107,7 @@ def _handle_http_error(
103107
104108
105109def _handle_http_successful (
106- request : web .Request ,
107- exception : web .HTTPSuccessful ,
110+ request : web .Request , exception : web .HTTPSuccessful
108111) -> web .HTTPSuccessful :
109112 """Handle successful HTTP responses, ensuring they're properly enveloped."""
110113 assert request # nosec
@@ -124,35 +127,30 @@ def _handle_http_successful(
124127 return exception
125128
126129
127- def _handle_not_implemented_error (
130+ def _handle_exception_as_http_error (
128131 request : web .Request ,
129- exception : NotImplementedError ,
132+ exception : Exception ,
133+ status_code : int ,
130134 * ,
131135 skip_internal_error_details : bool ,
132- ) -> web .HTTPNotImplemented :
133- """Handle NotImplementedError by converting to appropriate HTTP error."""
136+ ) -> HTTPError :
137+ """
138+ Generic handler for exceptions that map to specific HTTP status codes.
139+ Converts the status code to the appropriate HTTP error class and creates a response.
140+ """
134141 assert request # nosec
135142
136- return create_http_error (
137- exception ,
138- f"{ exception } " ,
139- web .HTTPNotImplemented ,
140- skip_internal_error_details = skip_internal_error_details ,
141- )
142-
143+ http_error_cls = get_http_error_class_or_none (status_code )
144+ if http_error_cls is None :
145+ msg = (
146+ f"No HTTP error class found for status code { status_code } , falling back to 500" ,
147+ )
148+ raise ValueError (msg )
143149
144- def _handle_timeout_error (
145- request : web .Request ,
146- exception : TimeoutError ,
147- * ,
148- skip_internal_error_details : bool ,
149- ) -> web .HTTPGatewayTimeout :
150- """Handle TimeoutError by converting to appropriate HTTP error."""
151- assert request # nosec
152150 return create_http_error (
153151 exception ,
154152 f"{ exception } " ,
155- web . HTTPGatewayTimeout ,
153+ http_error_cls ,
156154 skip_internal_error_details = skip_internal_error_details ,
157155 )
158156
@@ -183,17 +181,24 @@ async def _middleware_handler(request: web.Request, handler: Handler):
183181 result = exc
184182
185183 except NotImplementedError as exc :
186- result = _handle_not_implemented_error (
187- request , exc , skip_internal_error_details = _is_prod
184+ result = _handle_exception_as_http_error (
185+ request ,
186+ exc ,
187+ status .HTTP_501_NOT_IMPLEMENTED ,
188+ skip_internal_error_details = _is_prod ,
188189 )
190+
189191 except TimeoutError as exc :
190- result = _handle_timeout_error (
191- request , exc , skip_internal_error_details = _is_prod
192+ result = _handle_exception_as_http_error (
193+ request ,
194+ exc ,
195+ status .HTTP_504_GATEWAY_TIMEOUT ,
196+ skip_internal_error_details = _is_prod ,
192197 )
193198
194199 except Exception as exc : # pylint: disable=broad-except
195200 #
196- # Last resort for unexpected exceptions (including those in handlers!)
201+ # Last resort for unexpected exceptions (including those raise by the exception handlers!)
197202 #
198203 result = _handle_unexpected_exception_as_500 (
199204 request , exc , skip_internal_error_details = _is_prod
0 commit comments