Skip to content

Commit c5270e7

Browse files
author
Yurii Kulaksyz
committed
fix: add exception handling for POST request failures in StreamableHTTP client
1 parent 679b229 commit c5270e7

File tree

1 file changed

+40
-30
lines changed

1 file changed

+40
-30
lines changed

src/mcp/client/streamable_http.py

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -255,40 +255,50 @@ async def _handle_post_request(self, ctx: RequestContext) -> None:
255255
headers = self._prepare_request_headers(ctx.headers)
256256
message = ctx.session_message.message
257257
is_initialization = self._is_initialization_request(message)
258+
try:
259+
async with ctx.client.stream(
260+
"POST",
261+
self.url,
262+
json=message.model_dump(by_alias=True, mode="json", exclude_none=True),
263+
headers=headers,
264+
) as response:
265+
if response.status_code == 202:
266+
logger.debug("Received 202 Accepted")
267+
return
258268

259-
async with ctx.client.stream(
260-
"POST",
261-
self.url,
262-
json=message.model_dump(by_alias=True, mode="json", exclude_none=True),
263-
headers=headers,
264-
) as response:
265-
if response.status_code == 202:
266-
logger.debug("Received 202 Accepted")
267-
return
268-
269-
if response.status_code == 404:
270-
if isinstance(message.root, JSONRPCRequest):
271-
await self._send_session_terminated_error(
272-
ctx.read_stream_writer,
273-
message.root.id,
274-
)
275-
return
269+
if response.status_code == 404:
270+
if isinstance(message.root, JSONRPCRequest):
271+
await self._send_session_terminated_error(
272+
ctx.read_stream_writer,
273+
message.root.id,
274+
)
275+
return
276276

277-
response.raise_for_status()
278-
if is_initialization:
279-
self._maybe_extract_session_id_from_response(response)
277+
response.raise_for_status()
278+
if is_initialization:
279+
self._maybe_extract_session_id_from_response(response)
280280

281-
content_type = response.headers.get(CONTENT_TYPE, "").lower()
281+
content_type = response.headers.get(CONTENT_TYPE, "").lower()
282282

283-
if content_type.startswith(JSON):
284-
await self._handle_json_response(response, ctx.read_stream_writer, is_initialization)
285-
elif content_type.startswith(SSE):
286-
await self._handle_sse_response(response, ctx, is_initialization)
287-
else:
288-
await self._handle_unexpected_content_type(
289-
content_type,
290-
ctx.read_stream_writer,
291-
)
283+
if content_type.startswith(JSON):
284+
await self._handle_json_response(response, ctx.read_stream_writer, is_initialization)
285+
elif content_type.startswith(SSE):
286+
await self._handle_sse_response(response, ctx, is_initialization)
287+
else:
288+
await self._handle_unexpected_content_type(
289+
content_type,
290+
ctx.read_stream_writer,
291+
)
292+
except Exception as exc:
293+
logger.error(f"Error in _handle_post_request: {exc}")
294+
request_id = "Unknown"
295+
if isinstance(message.root, JSONRPCRequest):
296+
request_id = message.root.id
297+
error_response = JSONRPCError(
298+
jsonrpc="2.0", id=request_id, error=ErrorData(code=-32603, message=f"Transport error: {str(exc)}")
299+
)
300+
error_session_message = SessionMessage(JSONRPCMessage(error_response))
301+
await ctx.read_stream_writer.send(error_session_message)
292302

293303
async def _handle_json_response(
294304
self,

0 commit comments

Comments
 (0)