getsentry / getsentry/sentry-python

MCPIntegration bypasses ignore_errors when FastMCP wraps exceptions in ToolError

未关闭
#5,473 2 条评论 0 个 reaction 已指派 1 人 已被 @alexander-alderman-webb 认领 在 GitHub 查看
Bug Errors Python
主要语言
Python
星标
2.2k
派生
669
平均合并
1 天 1 小时
30 天内合并 PR
213

描述

## 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

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。