Skip to content

Commit 04eb963

Browse files
committed
test: validate the patch merged in fastmcp works as expected
1 parent a9155e9 commit 04eb963

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import mcp.types as mt
16+
import pytest
17+
from fastmcp import FastMCP
18+
from fastmcp.client import Client
19+
from fastmcp.server.middleware import Middleware, MiddlewareContext
20+
from mcp import McpError
21+
from mcp.types import ErrorData
22+
23+
24+
@pytest.mark.asyncio
25+
async def test_fastmcp_handles_initialize_error_from_middleware():
26+
"""Test that fastmcp properly handles McpError raised during initialization middleware.
27+
28+
This validates that the fix from https://github.com/jlowin/fastmcp/pull/2531 works,
29+
ensuring that initialization errors are sent back to the client instead of crashing.
30+
"""
31+
32+
class InitializeErrorMiddleware(Middleware):
33+
"""Middleware that raises an error during initialization."""
34+
35+
async def on_initialize(
36+
self,
37+
context: MiddlewareContext[mt.InitializeRequest],
38+
call_next,
39+
):
40+
raise McpError(ErrorData(code=-1, message='Initialization failed from middleware'))
41+
42+
server = FastMCP('test-server')
43+
server.add_middleware(InitializeErrorMiddleware())
44+
45+
@server.tool()
46+
def test_tool() -> str:
47+
"""A test tool."""
48+
return 'success'
49+
50+
client = Client(server)
51+
52+
# The client should receive the error during initialization
53+
with pytest.raises(McpError) as exc_info:
54+
async with client:
55+
pass
56+
57+
# Verify the error contains our custom error data
58+
assert exc_info.value.error.code == -1
59+
assert exc_info.value.error.message == 'Initialization failed from middleware'
60+
61+
62+
@pytest.mark.asyncio
63+
async def test_fastmcp_handles_error_after_initialization_completes():
64+
"""Test that fastmcp handles McpError raised AFTER initialization completes.
65+
66+
This validates that when an error is raised after call_next (when responder is already
67+
completed), fastmcp logs a warning but doesn't crash. The client receives the successful
68+
initialization response, not the error.
69+
70+
This is a current limitation of fastmcp - errors raised after call_next cannot be sent
71+
to the client because the response has already been sent.
72+
"""
73+
server = FastMCP('test-server')
74+
75+
class PostInitializeErrorMiddleware(Middleware):
76+
"""Middleware that raises an error AFTER initialization completes."""
77+
78+
async def on_initialize(
79+
self,
80+
context: MiddlewareContext[mt.InitializeRequest],
81+
call_next,
82+
):
83+
await call_next(context)
84+
# Raising error after call_next - responder is already completed
85+
raise McpError(ErrorData(code=-1, message='Error after initialization'))
86+
87+
server.add_middleware(PostInitializeErrorMiddleware())
88+
89+
@server.tool()
90+
def test_tool() -> str:
91+
"""A test tool."""
92+
return 'success'
93+
94+
client = Client(server)
95+
96+
# Client should still initialize successfully because the error happens after response is sent
97+
async with client:
98+
# Verify we can list tools - initialization succeeded despite the error
99+
tools = await client.list_tools()
100+
assert len(tools) > 0
101+
assert tools[0].name == 'test_tool'

0 commit comments

Comments
 (0)