mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(mcp): classify a cancelled per-server fetch instead of reporting a healthy empty server
A cancelled fetch absorbed to [] made that server contribute ServerListOk(tool_count=0), the exact healthy-but-empty impostor this change removes. Cancellation stays suppressed (the pre-existing choice); it now carries an internal fault so outcomes stay truthful
This commit is contained in:
parent
f776ea7f9b
commit
eefd5e31e5
2 changed files with 22 additions and 2 deletions
|
|
@ -3393,9 +3393,9 @@ class MCPServerManager:
|
|||
except TimeoutError as e:
|
||||
verbose_logger.warning(f"Timeout while listing tools from {server_name}")
|
||||
raise MCPServerListError(ServerListFault(tag="timeout"), server_name) from e
|
||||
except asyncio.CancelledError:
|
||||
except asyncio.CancelledError as e:
|
||||
verbose_logger.warning(f"Task cancelled while listing tools from {server_name}")
|
||||
return []
|
||||
raise MCPServerListError(ServerListFault(tag="internal"), server_name) from e
|
||||
except ConnectionError as e:
|
||||
verbose_logger.warning(f"Connection error while listing tools from {server_name}: {str(e)}")
|
||||
raise MCPServerListError(ServerListFault(tag="unreachable"), server_name) from e
|
||||
|
|
|
|||
|
|
@ -74,3 +74,23 @@ def test_wire_value_carries_no_prose():
|
|||
)
|
||||
def test_single_upstream_http_status_is_truthful(tag, status_code, expected):
|
||||
assert list_fault_http_status(ServerListFault(tag=tag, status_code=status_code)) == expected
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_cancelled_fetch_is_a_classified_fault_not_a_healthy_empty_server():
|
||||
"""A cancelled per-server fetch must not masquerade as ok(tool_count=0): cancellation was already
|
||||
suppressed before the outcome plumbing existed, so it stays suppressed, but as an internal fault
|
||||
the outcome reporting can see."""
|
||||
import asyncio
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
from litellm.proxy._experimental.mcp_server.mcp_server_manager import MCPServerManager
|
||||
|
||||
manager = MCPServerManager()
|
||||
client = MagicMock()
|
||||
client.list_tools = AsyncMock(side_effect=asyncio.CancelledError())
|
||||
|
||||
with pytest.raises(MCPServerListError) as exc_info:
|
||||
await manager._fetch_tools_with_timeout(client, "cancelled_srv")
|
||||
|
||||
assert exc_info.value.fault.tag == "internal"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue