fix: handle ToolError exceptions in MCP clients to reduce production alerts (#8599)
Add ToolError to exception handling alongside McpError in MCP client classes. ToolError is raised by fastmcp for input validation errors (e.g., missing required properties like 'filename'). Both error types are expected user-facing errors from external MCP servers and should be logged at warning/debug level to avoid triggering production alerts. Fixes issue with production error: "fastmcp.exceptions.ToolError: Input validation error: 'filename' is a required property" 🤖 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: datadog-official[bot] <datadog-official[bot]@users.noreply.github.com> Co-authored-by: Kian Jones <11655409+kianjones9@users.noreply.github.com>
This commit is contained in:
committed by
Sarah Wooders
parent
f67af1b13d
commit
a5108c96b4
@@ -81,10 +81,11 @@ class AsyncBaseMCPClient:
|
||||
try:
|
||||
result = await self.session.call_tool(tool_name, tool_args)
|
||||
except Exception as e:
|
||||
if e.__class__.__name__ == "McpError":
|
||||
# MCP errors are typically user-facing issues from external MCP servers
|
||||
# (e.g., resource not found, invalid arguments, permission errors)
|
||||
# Log at debug level to avoid triggering production alerts for expected failures
|
||||
# ToolError is raised by fastmcp for input validation errors (e.g., missing required properties)
|
||||
# McpError is raised for other MCP-related errors
|
||||
# Both are expected user-facing issues from external MCP servers
|
||||
# Log at debug level to avoid triggering production alerts for expected failures
|
||||
if e.__class__.__name__ in ("McpError", "ToolError"):
|
||||
logger.debug(f"MCP tool '{tool_name}' execution failed: {str(e)}")
|
||||
raise
|
||||
|
||||
|
||||
@@ -128,7 +128,10 @@ class AsyncFastMCPSSEClient:
|
||||
try:
|
||||
result = await self.client.call_tool(tool_name, tool_args)
|
||||
except Exception as e:
|
||||
if e.__class__.__name__ == "McpError":
|
||||
# ToolError is raised by fastmcp for input validation errors (e.g., missing required properties)
|
||||
# McpError is raised for other MCP-related errors
|
||||
# Both are expected user-facing errors from MCP tools, log at warning level
|
||||
if e.__class__.__name__ in ("McpError", "ToolError"):
|
||||
logger.warning(f"MCP tool '{tool_name}' execution failed: {str(e)}")
|
||||
raise
|
||||
|
||||
@@ -270,7 +273,10 @@ class AsyncFastMCPStreamableHTTPClient:
|
||||
try:
|
||||
result = await self.client.call_tool(tool_name, tool_args)
|
||||
except Exception as e:
|
||||
if e.__class__.__name__ == "McpError":
|
||||
# ToolError is raised by fastmcp for input validation errors (e.g., missing required properties)
|
||||
# McpError is raised for other MCP-related errors
|
||||
# Both are expected user-facing errors from MCP tools, log at warning level
|
||||
if e.__class__.__name__ in ("McpError", "ToolError"):
|
||||
logger.warning(f"MCP tool '{tool_name}' execution failed: {str(e)}")
|
||||
raise
|
||||
|
||||
|
||||
Reference in New Issue
Block a user