getsentry / getsentry/sentry-python
MCPIntegration bypasses ignore_errors when FastMCP wraps exceptions in ToolError
- Lenguaje dominante
- Python
- Estrellas
- 2.2k
- Forks
- 669
- Merge medio
- 1 d 40 min
- PR fusionados (30 d)
- 212
Descripción
## Problem
The `MCPIntegration` (auto-enabled since sentry-sdk 2.45) captures exceptions that should be filtered by `ignore_errors` because it sees the FastMCP-wrapped `ToolError` instead of the original exception type.
When using `ignore_errors` to suppress specific exception types raised by MCP tool handlers, the filtering doesn't work because of the order of exception wrapping:
1. Tool handler raises a custom exception (e.g. `ExpectedToolError`)
2. FastMCP's `tool_manager.call_tool()` catches it and wraps it in `ToolError`: `raise ToolError(...) from e`
3. `ToolError` propagates up through FastMCP's `_call_tool_mcp`
4. The `MCPIntegration`'s `_async_handler_wrapper` catches `ToolError` and calls `sentry_sdk.capture_exception(e)` ([link](https://github.com/getsentry/sentry-python/blob/master/sentry_sdk/integrations/mcp.py#L429))
5. `_is_ignored_error` checks `issubclass(ToolError, ExpectedToolError)` → **False** → event is sent to Sentry
The `ignore_errors` configuration never sees the original exception type because FastMCP has already wrapped it.
## Expected Behavior
Exceptions listed in `ignore_errors` (or their subclasses) should not be sent to Sentry, even when FastMCP wraps them in `ToolError`. The integration should either walk the exception chain (`__cause__`) or skip capturing exceptions that are already handled by the framework.
## Reproduction
```python
import sentry_sdk
from sentry_sdk.integrations.mcp import MCPIntegration
from fastmcp import FastMCP
class ExpectedToolError(Exception):
"""Should not be reported to Sentry."""
pass
sentry_sdk.init(
dsn="...",
ignore_errors=[ExpectedToolError],
)
mcp = FastMCP("test")
@mcp.tool()
def my_tool() -> str:
raise ExpectedToolError("This is expected and should not go to Sentry")
```
When `my_tool` is called, the `ExpectedToolError` ends up in Sentry because the MCPIntegration captures the wrapping `ToolError`.
## Workaround
Disable the `MCPIntegration` if you handle MCP error reporting yourself:
```python
sentry_sdk.init(
dsn="...",
disabled_integrations=[MCPIntegration()],
ignore_errors=[ExpectedToolError],
)
```
## Environment
- sentry-sdk: 2.51.0
- fastmcp: 2.14.4
- mcp: 1.26.0
- Python: 3.13
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.