mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-23 22:14:18 +02:00
Add mounted_components_raise_on_load_error setting for debugging (#1534)
Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com> Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
This commit is contained in:
parent
ec015de3b0
commit
26969e80c3
5 changed files with 62 additions and 1 deletions
|
|
@ -80,6 +80,8 @@ class PromptManager:
|
|||
logger.warning(
|
||||
f"Failed to get prompts from server: {mounted.server.name!r}, mounted at: {mounted.prefix!r}: {e}"
|
||||
)
|
||||
if settings.mounted_components_raise_on_load_error:
|
||||
raise
|
||||
continue
|
||||
|
||||
# Finally, add local prompts, which always take precedence
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ class ResourceManager:
|
|||
logger.warning(
|
||||
f"Failed to get resources from server: {mounted.server.name!r}, mounted at: {mounted.prefix!r}: {e}"
|
||||
)
|
||||
if settings.mounted_components_raise_on_load_error:
|
||||
raise
|
||||
continue
|
||||
|
||||
# Finally, add local resources, which always take precedence
|
||||
|
|
@ -165,6 +167,8 @@ class ResourceManager:
|
|||
logger.warning(
|
||||
f"Failed to get templates from server: {mounted.server.name!r}, mounted at: {mounted.prefix!r}: {e}"
|
||||
)
|
||||
if settings.mounted_components_raise_on_load_error:
|
||||
raise
|
||||
continue
|
||||
|
||||
# Finally, add local templates, which always take precedence
|
||||
|
|
|
|||
|
|
@ -320,6 +320,20 @@ class Settings(BaseSettings):
|
|||
),
|
||||
] = True
|
||||
|
||||
mounted_components_raise_on_load_error: Annotated[
|
||||
bool,
|
||||
Field(
|
||||
default=False,
|
||||
description=inspect.cleandoc(
|
||||
"""
|
||||
If True, errors encountered when loading mounted components (tools, resources, prompts)
|
||||
will be raised instead of logged as warnings. This is useful for debugging
|
||||
but will interrupt normal operation.
|
||||
"""
|
||||
),
|
||||
),
|
||||
] = False
|
||||
|
||||
|
||||
def __getattr__(name: str):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ class ToolManager:
|
|||
logger.warning(
|
||||
f"Failed to get tools from server: {mounted.server.name!r}, mounted at: {mounted.prefix!r}: {e}"
|
||||
)
|
||||
if settings.mounted_components_raise_on_load_error:
|
||||
raise
|
||||
continue
|
||||
|
||||
# Finally, add local tools, which always take precedence
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from fastmcp.exceptions import NotFoundError, ToolError
|
|||
from fastmcp.tools import FunctionTool, ToolManager
|
||||
from fastmcp.tools.tool import Tool
|
||||
from fastmcp.tools.tool_transform import ArgTransformConfig, ToolTransformConfig
|
||||
from fastmcp.utilities.tests import caplog_for_fastmcp
|
||||
from fastmcp.utilities.tests import caplog_for_fastmcp, temporary_settings
|
||||
from fastmcp.utilities.types import Image
|
||||
|
||||
|
||||
|
|
@ -996,3 +996,42 @@ class TestToolErrorHandling:
|
|||
# Exception message should contain the tool name but not the internal details
|
||||
assert "Error calling tool 'async_buggy_tool'" in str(excinfo.value)
|
||||
assert "Internal async error details" not in str(excinfo.value)
|
||||
|
||||
|
||||
class TestMountedComponentsRaiseOnLoadError:
|
||||
"""Test the mounted_components_raise_on_load_error setting."""
|
||||
|
||||
async def test_mounted_components_raise_on_load_error_default_false(self):
|
||||
"""Test that by default, mounted component load errors are warned and not raised."""
|
||||
import fastmcp
|
||||
|
||||
# Ensure default setting is False
|
||||
assert fastmcp.settings.mounted_components_raise_on_load_error is False
|
||||
|
||||
parent_mcp = FastMCP("ParentServer")
|
||||
child_mcp = FastMCP("FailingChildServer")
|
||||
|
||||
# Create a failing mounted server by corrupting it
|
||||
parent_mcp.mount(child_mcp, prefix="child")
|
||||
# Corrupt the child server to make it fail during tool loading
|
||||
child_mcp._tool_manager._mounted_servers.append("invalid") # type: ignore
|
||||
|
||||
# Should not raise, just warn
|
||||
tools = await parent_mcp._tool_manager.list_tools()
|
||||
assert isinstance(tools, list) # Should return empty list, not raise
|
||||
|
||||
async def test_mounted_components_raise_on_load_error_true(self):
|
||||
"""Test that when enabled, mounted component load errors are raised."""
|
||||
parent_mcp = FastMCP("ParentServer")
|
||||
child_mcp = FastMCP("FailingChildServer")
|
||||
|
||||
# Create a failing mounted server
|
||||
parent_mcp.mount(child_mcp, prefix="child")
|
||||
# Corrupt the child server to make it fail during tool loading
|
||||
child_mcp._tool_manager._mounted_servers.append("invalid") # type: ignore
|
||||
|
||||
# Use temporary settings context manager
|
||||
with temporary_settings(mounted_components_raise_on_load_error=True):
|
||||
# Should raise the exception
|
||||
with pytest.raises(AttributeError, match=""):
|
||||
await parent_mcp._tool_manager.list_tools()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue