refactor: McpError renamed to MCPError and flatten parameters (#1956)
Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
This commit is contained in:
parent
65c614e48e
commit
acba5478a9
5 changed files with 253 additions and 326 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import pytest
|
||||
|
||||
from mcp.shared.exceptions import McpError, UrlElicitationRequiredError
|
||||
from mcp.shared.exceptions import MCPError, UrlElicitationRequiredError
|
||||
from mcp.types import URL_ELICITATION_REQUIRED, ElicitRequestURLParams, ErrorData
|
||||
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ def test_url_elicitation_required_error_data_contains_elicitations() -> None:
|
|||
|
||||
|
||||
def test_url_elicitation_required_error_inherits_from_mcp_error() -> None:
|
||||
"""Test that UrlElicitationRequiredError inherits from McpError."""
|
||||
"""Test that UrlElicitationRequiredError inherits from MCPError."""
|
||||
elicitation = ElicitRequestURLParams(
|
||||
mode="url",
|
||||
message="Auth required",
|
||||
|
|
@ -146,7 +146,7 @@ def test_url_elicitation_required_error_inherits_from_mcp_error() -> None:
|
|||
)
|
||||
error = UrlElicitationRequiredError([elicitation])
|
||||
|
||||
assert isinstance(error, McpError)
|
||||
assert isinstance(error, MCPError)
|
||||
assert isinstance(error, Exception)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import mcp.types as types
|
|||
from mcp import Client
|
||||
from mcp.client.session import ClientSession
|
||||
from mcp.server.lowlevel.server import Server
|
||||
from mcp.shared.exceptions import McpError
|
||||
from mcp.shared.exceptions import MCPError
|
||||
from mcp.shared.memory import create_client_server_memory_streams
|
||||
from mcp.shared.message import SessionMessage
|
||||
from mcp.types import (
|
||||
|
|
@ -77,7 +77,7 @@ async def test_request_cancellation():
|
|||
types.CallToolResult,
|
||||
)
|
||||
pytest.fail("Request should have been cancelled") # pragma: no cover
|
||||
except McpError as e:
|
||||
except MCPError as e:
|
||||
# Expected - request was cancelled
|
||||
assert "Request cancelled" in str(e)
|
||||
ev_cancelled.set()
|
||||
|
|
@ -164,7 +164,7 @@ async def test_error_response_id_type_mismatch_string_to_int():
|
|||
but the client sent "id": 0 (integer).
|
||||
"""
|
||||
ev_error_received = anyio.Event()
|
||||
error_holder: list[McpError] = []
|
||||
error_holder: list[MCPError | Exception] = []
|
||||
|
||||
async with create_client_server_memory_streams() as (client_streams, server_streams):
|
||||
client_read, client_write = client_streams
|
||||
|
|
@ -191,8 +191,8 @@ async def test_error_response_id_type_mismatch_string_to_int():
|
|||
nonlocal error_holder
|
||||
try:
|
||||
await client_session.send_ping()
|
||||
pytest.fail("Expected McpError to be raised") # pragma: no cover
|
||||
except McpError as e:
|
||||
pytest.fail("Expected MCPError to be raised") # pragma: no cover
|
||||
except MCPError as e:
|
||||
error_holder.append(e)
|
||||
ev_error_received.set()
|
||||
|
||||
|
|
@ -246,7 +246,7 @@ async def test_response_id_non_numeric_string_no_match():
|
|||
request_read_timeout_seconds=0.5,
|
||||
)
|
||||
pytest.fail("Expected timeout") # pragma: no cover
|
||||
except McpError as e:
|
||||
except MCPError as e:
|
||||
assert "Timed out" in str(e)
|
||||
ev_timeout.set()
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ async def test_connection_closed():
|
|||
# any request will do
|
||||
await client_session.initialize()
|
||||
pytest.fail("Request should have errored") # pragma: no cover
|
||||
except McpError as e:
|
||||
except MCPError as e:
|
||||
# Expected - request errored
|
||||
assert "Connection closed" in str(e)
|
||||
ev_response.set()
|
||||
|
|
|
|||
|
|
@ -25,10 +25,9 @@ from mcp.client.sse import _extract_session_id_from_endpoint, sse_client
|
|||
from mcp.server import Server
|
||||
from mcp.server.sse import SseServerTransport
|
||||
from mcp.server.transport_security import TransportSecuritySettings
|
||||
from mcp.shared.exceptions import McpError
|
||||
from mcp.shared.exceptions import MCPError
|
||||
from mcp.types import (
|
||||
EmptyResult,
|
||||
ErrorData,
|
||||
Implementation,
|
||||
InitializeResult,
|
||||
JSONRPCResponse,
|
||||
|
|
@ -70,7 +69,7 @@ class ServerTest(Server): # pragma: no cover
|
|||
await anyio.sleep(2.0)
|
||||
return f"Slow response from {parsed.netloc}"
|
||||
|
||||
raise McpError(error=ErrorData(code=404, message="OOPS! no resource with that URI was found"))
|
||||
raise MCPError(code=404, message="OOPS! no resource with that URI was found")
|
||||
|
||||
@self.list_tools()
|
||||
async def handle_list_tools() -> list[Tool]:
|
||||
|
|
@ -266,7 +265,7 @@ async def test_sse_client_exception_handling(
|
|||
initialized_sse_client_session: ClientSession,
|
||||
) -> None:
|
||||
session = initialized_sse_client_session
|
||||
with pytest.raises(McpError, match="OOPS! no resource with that URI was found"):
|
||||
with pytest.raises(MCPError, match="OOPS! no resource with that URI was found"):
|
||||
await session.read_resource(uri="xxx://will-not-work")
|
||||
|
||||
|
||||
|
|
@ -282,7 +281,7 @@ async def test_sse_client_timeout( # pragma: no cover
|
|||
assert isinstance(response, ReadResourceResult)
|
||||
|
||||
with anyio.move_on_after(3):
|
||||
with pytest.raises(McpError, match="Read timed out"):
|
||||
with pytest.raises(MCPError, match="Read timed out"):
|
||||
response = await session.read_resource(uri="slow://2")
|
||||
# we should receive an error here
|
||||
return
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ from starlette.requests import Request
|
|||
from starlette.routing import Mount
|
||||
|
||||
import mcp.types as types
|
||||
from mcp import MCPError
|
||||
from mcp.client.session import ClientSession
|
||||
from mcp.client.streamable_http import StreamableHTTPTransport, streamable_http_client
|
||||
from mcp.server import Server
|
||||
|
|
@ -44,16 +45,9 @@ from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
|
|||
from mcp.server.transport_security import TransportSecuritySettings
|
||||
from mcp.shared._httpx_utils import create_mcp_http_client
|
||||
from mcp.shared.context import RequestContext
|
||||
from mcp.shared.exceptions import McpError
|
||||
from mcp.shared.message import ClientMessageMetadata, ServerMessageMetadata, SessionMessage
|
||||
from mcp.shared.session import RequestResponder
|
||||
from mcp.types import (
|
||||
InitializeResult,
|
||||
JSONRPCRequest,
|
||||
TextContent,
|
||||
TextResourceContents,
|
||||
Tool,
|
||||
)
|
||||
from mcp.types import InitializeResult, JSONRPCRequest, TextContent, TextResourceContents, Tool
|
||||
from tests.test_helpers import wait_for_server
|
||||
|
||||
# Test constants
|
||||
|
|
@ -987,11 +981,7 @@ async def initialized_client_session(basic_server: None, basic_server_url: str):
|
|||
@pytest.mark.anyio
|
||||
async def test_streamable_http_client_basic_connection(basic_server: None, basic_server_url: str):
|
||||
"""Test basic client connection with initialization."""
|
||||
async with streamable_http_client(f"{basic_server_url}/mcp") as (
|
||||
read_stream,
|
||||
write_stream,
|
||||
_,
|
||||
):
|
||||
async with streamable_http_client(f"{basic_server_url}/mcp") as (read_stream, write_stream, _):
|
||||
async with ClientSession(
|
||||
read_stream,
|
||||
write_stream,
|
||||
|
|
@ -1030,7 +1020,7 @@ async def test_streamable_http_client_tool_invocation(initialized_client_session
|
|||
@pytest.mark.anyio
|
||||
async def test_streamable_http_client_error_handling(initialized_client_session: ClientSession):
|
||||
"""Test error handling in client."""
|
||||
with pytest.raises(McpError) as exc_info:
|
||||
with pytest.raises(MCPError) as exc_info:
|
||||
await initialized_client_session.read_resource(uri="unknown://test-error")
|
||||
assert exc_info.value.error.code == 0
|
||||
assert "Unknown resource: unknown://test-error" in exc_info.value.error.message
|
||||
|
|
@ -1067,15 +1057,8 @@ async def test_streamable_http_client_session_persistence(basic_server: None, ba
|
|||
@pytest.mark.anyio
|
||||
async def test_streamable_http_client_json_response(json_response_server: None, json_server_url: str):
|
||||
"""Test client with JSON response mode."""
|
||||
async with streamable_http_client(f"{json_server_url}/mcp") as (
|
||||
read_stream,
|
||||
write_stream,
|
||||
_,
|
||||
):
|
||||
async with ClientSession(
|
||||
read_stream,
|
||||
write_stream,
|
||||
) as session:
|
||||
async with streamable_http_client(f"{json_server_url}/mcp") as (read_stream, write_stream, _):
|
||||
async with ClientSession(read_stream, write_stream) as session:
|
||||
# Initialize the session
|
||||
result = await session.initialize()
|
||||
assert isinstance(result, InitializeResult)
|
||||
|
|
@ -1104,11 +1087,7 @@ async def test_streamable_http_client_get_stream(basic_server: None, basic_serve
|
|||
if isinstance(message, types.ServerNotification): # pragma: no branch
|
||||
notifications_received.append(message)
|
||||
|
||||
async with streamable_http_client(f"{basic_server_url}/mcp") as (
|
||||
read_stream,
|
||||
write_stream,
|
||||
_,
|
||||
):
|
||||
async with streamable_http_client(f"{basic_server_url}/mcp") as (read_stream, write_stream, _):
|
||||
async with ClientSession(read_stream, write_stream, message_handler=message_handler) as session:
|
||||
# Initialize the session - this triggers the GET stream setup
|
||||
result = await session.initialize()
|
||||
|
|
@ -1137,11 +1116,7 @@ async def test_streamable_http_client_session_termination(basic_server: None, ba
|
|||
captured_session_id = None
|
||||
|
||||
# Create the streamable_http_client with a custom httpx client to capture headers
|
||||
async with streamable_http_client(f"{basic_server_url}/mcp") as (
|
||||
read_stream,
|
||||
write_stream,
|
||||
get_session_id,
|
||||
):
|
||||
async with streamable_http_client(f"{basic_server_url}/mcp") as (read_stream, write_stream, get_session_id):
|
||||
async with ClientSession(read_stream, write_stream) as session:
|
||||
# Initialize the session
|
||||
result = await session.initialize()
|
||||
|
|
@ -1165,7 +1140,7 @@ async def test_streamable_http_client_session_termination(basic_server: None, ba
|
|||
):
|
||||
async with ClientSession(read_stream, write_stream) as session: # pragma: no branch
|
||||
# Attempt to make a request after termination
|
||||
with pytest.raises(McpError, match="Session terminated"): # pragma: no branch
|
||||
with pytest.raises(MCPError, match="Session terminated"): # pragma: no branch
|
||||
await session.list_tools()
|
||||
|
||||
|
||||
|
|
@ -1201,11 +1176,7 @@ async def test_streamable_http_client_session_termination_204(
|
|||
captured_session_id = None
|
||||
|
||||
# Create the streamable_http_client with a custom httpx client to capture headers
|
||||
async with streamable_http_client(f"{basic_server_url}/mcp") as (
|
||||
read_stream,
|
||||
write_stream,
|
||||
get_session_id,
|
||||
):
|
||||
async with streamable_http_client(f"{basic_server_url}/mcp") as (read_stream, write_stream, get_session_id):
|
||||
async with ClientSession(read_stream, write_stream) as session:
|
||||
# Initialize the session
|
||||
result = await session.initialize()
|
||||
|
|
@ -1229,10 +1200,7 @@ async def test_streamable_http_client_session_termination_204(
|
|||
):
|
||||
async with ClientSession(read_stream, write_stream) as session: # pragma: no branch
|
||||
# Attempt to make a request after termination
|
||||
with pytest.raises( # pragma: no branch
|
||||
McpError,
|
||||
match="Session terminated",
|
||||
):
|
||||
with pytest.raises(MCPError, match="Session terminated"): # pragma: no branch
|
||||
await session.list_tools()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,20 +12,12 @@ from starlette.applications import Starlette
|
|||
from starlette.routing import WebSocketRoute
|
||||
from starlette.websockets import WebSocket
|
||||
|
||||
from mcp import MCPError
|
||||
from mcp.client.session import ClientSession
|
||||
from mcp.client.websocket import websocket_client
|
||||
from mcp.server import Server
|
||||
from mcp.server.websocket import websocket_server
|
||||
from mcp.shared.exceptions import McpError
|
||||
from mcp.types import (
|
||||
EmptyResult,
|
||||
ErrorData,
|
||||
InitializeResult,
|
||||
ReadResourceResult,
|
||||
TextContent,
|
||||
TextResourceContents,
|
||||
Tool,
|
||||
)
|
||||
from mcp.types import EmptyResult, InitializeResult, ReadResourceResult, TextContent, TextResourceContents, Tool
|
||||
from tests.test_helpers import wait_for_server
|
||||
|
||||
SERVER_NAME = "test_server_for_WS"
|
||||
|
|
@ -58,7 +50,7 @@ class ServerTest(Server): # pragma: no cover
|
|||
await anyio.sleep(2.0)
|
||||
return f"Slow response from {parsed.netloc}"
|
||||
|
||||
raise McpError(error=ErrorData(code=404, message="OOPS! no resource with that URI was found"))
|
||||
raise MCPError(code=404, message="OOPS! no resource with that URI was found")
|
||||
|
||||
@self.list_tools()
|
||||
async def handle_list_tools() -> list[Tool]:
|
||||
|
|
@ -84,12 +76,7 @@ def make_server_app() -> Starlette: # pragma: no cover
|
|||
async with websocket_server(websocket.scope, websocket.receive, websocket.send) as streams:
|
||||
await server.run(streams[0], streams[1], server.create_initialization_options())
|
||||
|
||||
app = Starlette(
|
||||
routes=[
|
||||
WebSocketRoute("/ws", endpoint=handle_ws),
|
||||
]
|
||||
)
|
||||
|
||||
app = Starlette(routes=[WebSocketRoute("/ws", endpoint=handle_ws)])
|
||||
return app
|
||||
|
||||
|
||||
|
|
@ -176,7 +163,7 @@ async def test_ws_client_exception_handling(
|
|||
initialized_ws_client_session: ClientSession,
|
||||
) -> None:
|
||||
"""Test exception handling in WebSocket communication"""
|
||||
with pytest.raises(McpError) as exc_info:
|
||||
with pytest.raises(MCPError) as exc_info:
|
||||
await initialized_ws_client_session.read_resource("unknown://example")
|
||||
assert exc_info.value.error.code == 404
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue