1111from aiohttp .web_exceptions import HTTPError
1212from aiohttp .web_request import Request
1313from aiohttp .web_response import StreamResponse
14- from common_library .error_codes import create_error_code
14+ from common_library .error_codes import ErrorCodeStr , create_error_code
1515from common_library .json_serialization import json_dumps , json_loads
1616from common_library .user_messages import user_message
17+ from models_library .basic_types import IDStr
1718from models_library .rest_error import ErrorGet , ErrorItemType , LogMessageType
19+ from servicelib .rest_constants import RESPONSE_MODEL_POLICY
1820from servicelib .status_codes_utils import is_5xx_server_error
1921
2022from ..logging_errors import create_troubleshotting_log_kwargs
2830 safe_status_message ,
2931 wrap_as_envelope ,
3032)
31- from .rest_utils import EnvelopeFactory
3233from .typing_extension import Handler , Middleware
3334from .web_exceptions_extension import get_http_error_class_or_none
3435
@@ -49,7 +50,7 @@ def is_api_request(request: web.Request, api_version: str) -> bool:
4950
5051def _create_error_context (
5152 request : web .BaseRequest , exception : Exception
52- ) -> tuple [str , dict [str , Any ]]:
53+ ) -> tuple [ErrorCodeStr , dict [str , Any ]]:
5354 """Create error code and context for logging purposes.
5455
5556 Returns:
@@ -66,7 +67,7 @@ def _create_error_context(
6667
6768def _log_5xx_server_error (
6869 request : web .BaseRequest , exception : Exception , user_error_msg : str
69- ) -> None :
70+ ) -> ErrorCodeStr :
7071 """Log 5XX server errors with error code and context."""
7172 error_code , error_context = _create_error_context (request , exception )
7273
@@ -78,6 +79,7 @@ def _log_5xx_server_error(
7879 error_code = error_code ,
7980 )
8081 )
82+ return error_code
8183
8284
8385def _handle_unexpected_exception_as_500 (
@@ -105,7 +107,10 @@ def _handle_unexpected_exception_as_500(
105107def _handle_http_error (
106108 request : web .BaseRequest , exception : web .HTTPError
107109) -> web .HTTPError :
108- """Handle standard HTTP errors by ensuring they're properly formatted."""
110+ """Handle standard HTTP errors by ensuring they're properly formatted.
111+
112+ NOTE: this needs further refactoring to avoid code duplication
113+ """
109114 assert request # nosec
110115 assert not exception .empty_body , "HTTPError should not have an empty body" # nosec
111116
@@ -118,6 +123,12 @@ def _handle_http_error(
118123 if not exception .text or not is_enveloped_from_text (exception .text ):
119124 # NOTE: aiohttp.HTTPException creates `text = f"{self.status}: {self.reason}"`
120125 user_error_msg = exception .text or "Unexpected error"
126+
127+ error_code = None
128+ if is_5xx_server_error (exception .status ):
129+ error_code = _log_5xx_server_error (request , exception , user_error_msg )
130+ error_code = IDStr (error_code )
131+
121132 error_model = ErrorGet (
122133 errors = [
123134 ErrorItemType .from_error (exception ),
@@ -127,11 +138,13 @@ def _handle_http_error(
127138 LogMessageType (message = user_error_msg , level = "ERROR" ),
128139 ],
129140 message = user_error_msg ,
141+ support_id = error_code ,
142+ )
143+ exception .text = json_dumps (
144+ wrap_as_envelope (
145+ error = error_model .model_dump (mode = "json" , ** RESPONSE_MODEL_POLICY )
146+ )
130147 )
131- exception .text = EnvelopeFactory (error = error_model ).as_text ()
132-
133- if is_5xx_server_error (exception .status ):
134- _log_5xx_server_error (request , exception , user_error_msg )
135148
136149 return exception
137150
0 commit comments