fix: wrap MCP client connection errors in ConnectionError (#8569)

The FastMCP clients were not properly wrapping exceptions from
`connect_to_server()`, causing raw RuntimeErrors (like DNS resolution
failures with "[Errno -2] Name or service not known") to propagate
up unchanged.

Changes:
- Both `AsyncFastMCPSSEClient` and `AsyncFastMCPStreamableHTTPClient`
  now properly catch all exceptions and wrap them in `ConnectionError`
- Added warning-level logging for failed connections
- Provides user-friendly error messages with the server URL

Fixes #8568
Related to #8499



🤖 Generated with [Letta Code](https://letta.com)

Co-authored-by: letta-code <248085862+letta-code@users.noreply.github.com>
Co-authored-by: Letta <noreply@letta.com>
Co-authored-by: Kian Jones <11655409+kianjones9@users.noreply.github.com>
This commit is contained in:
github-actions[bot]
2026-01-13 18:06:04 -08:00
committed by Sarah Wooders
parent e914075b04
commit ebc77d0950

View File

@@ -78,10 +78,21 @@ class AsyncFastMCPSSEClient:
except httpx.HTTPStatusError as e:
# Re-raise HTTP status errors for OAuth flow handling
if e.response.status_code == 401:
raise ConnectionError("401 Unauthorized")
raise e
raise ConnectionError("401 Unauthorized") from e
raise ConnectionError(f"HTTP error connecting to MCP server at {self.server_config.server_url}: {e}") from e
except ConnectionError:
# Re-raise ConnectionError as-is
raise
except Exception as e:
raise e
# MCP connection failures are often due to user misconfiguration, not system errors
# Log as warning for visibility in monitoring
logger.warning(
f"Connecting to MCP server failed. Please review your server config: {self.server_config.model_dump_json(indent=4)}. Error: {str(e)}"
)
raise ConnectionError(
f"Failed to connect to MCP server at '{self.server_config.server_url}'. "
f"Please check your configuration and ensure the server is accessible. Error: {str(e)}"
) from e
async def list_tools(self, serialize: bool = False) -> List[MCPTool]:
"""List available tools from the MCP server.
@@ -223,10 +234,21 @@ class AsyncFastMCPStreamableHTTPClient:
except httpx.HTTPStatusError as e:
# Re-raise HTTP status errors for OAuth flow handling
if e.response.status_code == 401:
raise ConnectionError("401 Unauthorized")
raise e
raise ConnectionError("401 Unauthorized") from e
raise ConnectionError(f"HTTP error connecting to MCP server at {self.server_config.server_url}: {e}") from e
except ConnectionError:
# Re-raise ConnectionError as-is
raise
except Exception as e:
raise e
# MCP connection failures are often due to user misconfiguration, not system errors
# Log as warning for visibility in monitoring
logger.warning(
f"Connecting to MCP server failed. Please review your server config: {self.server_config.model_dump_json(indent=4)}. Error: {str(e)}"
)
raise ConnectionError(
f"Failed to connect to MCP server at '{self.server_config.server_url}'. "
f"Please check your configuration and ensure the server is accessible. Error: {str(e)}"
) from e
async def list_tools(self, serialize: bool = False) -> List[MCPTool]:
"""List available tools from the MCP server.