99from karapace .version import __version__
1010from pydantic import BaseModel
1111from typing import overload , TypeVar , Union
12-
12+ from karapace . api . routers . requests import ErrorResponse
1313import aiohttp
1414import async_timeout
1515import logging
@@ -46,7 +46,7 @@ async def _forward_request_remote(
4646 * ,
4747 request : Request ,
4848 primary_url : str ,
49- ) -> bytes :
49+ ) -> tuple [ bytes , int ]: # Return both body and status code
5050 LOG .info ("Forwarding %s request to remote url: %r since we're not the master" , request .method , request .url )
5151 timeout = 60.0
5252 func = getattr (self ._forward_client , request .method .lower ())
@@ -60,16 +60,11 @@ async def _forward_request_remote(
6060 async with func (
6161 forward_url , headers = request .headers .mutablecopy (), data = body_data , ssl = self ._ssl_context
6262 ) as response :
63- if self ._acceptable_response_content_type (content_type = response .headers .get ("Content-Type" )):
64- return await response .text ()
65- LOG .error ("Unknown response for forwarded request: %s" , response )
66- raise HTTPException (
67- status_code = status .HTTP_500_INTERNAL_SERVER_ERROR ,
68- detail = {
69- "error_code" : status .HTTP_500_INTERNAL_SERVER_ERROR ,
70- "message" : "Unknown response for forwarded request." ,
71- },
72- )
63+ body = await response .text ()
64+ # Return body and status regardless of content type for error cases
65+ if not self ._acceptable_response_content_type (content_type = response .headers .get ("Content-Type" )):
66+ LOG .error ("Unknown response content type for forwarded request: %s" , response .headers .get ("Content-Type" ))
67+ return body , response .status
7368
7469 @overload
7570 async def forward_request_remote (
@@ -90,13 +85,27 @@ async def forward_request_remote(
9085 ) -> SimpleTypeResponse : ...
9186
9287 async def forward_request_remote (
93- self ,
94- * ,
95- request : Request ,
96- primary_url : str ,
97- response_type : type [BaseModelResponse ] | type [SimpleTypeResponse ],
98- ) -> BaseModelResponse | SimpleTypeResponse :
99- body = await self ._forward_request_remote (request = request , primary_url = primary_url )
88+ self ,
89+ * ,
90+ request : Request ,
91+ primary_url : str ,
92+ response_type : type [BaseModelResponse ] | type [SimpleTypeResponse ],
93+ ) -> BaseModelResponse | SimpleTypeResponse :
94+ body , http_status = await self ._forward_request_remote (request = request , primary_url = primary_url )
95+
96+ # If the leader returned an error status, parse and re-raise it
97+ if http_status >= 400 :
98+ try :
99+ error_data = json_decode (body )
100+ except Exception :
101+ error_data = {"error_code" : http_status , "message" : body }
102+
103+ raise HTTPException (
104+ status_code = http_status , # Use HTTP status, not error_code from body
105+ detail = error_data ,
106+ )
107+
108+ # Success case - parse according to expected response type
100109 if response_type is int :
101110 return int (body ) # type: ignore[return-value]
102111 if response_type == list [int ]:
0 commit comments