{"slug": "sentry-sdk-2-x-auto-integrations-flood-your-inbox-here-s-the-filter", "title": "Sentry SDK 2.x Auto-Integrations Flood Your Inbox — Here's the Filter", "summary": "HoneyChat, a Telegram-native AI companion with approximately 300 daily active users, experienced a surge from roughly 5 Sentry issues per day to over 4,000 after upgrading from Sentry SDK 1.x to 2.x. The upgrade automatically enabled integrations for Loguru, OpenAI, SQLAlchemy, asyncpg, Redis, and httpx, flooding the inbox with expected operational errors like rate limits, connection resets, and retry exceptions rather than actual bugs. The team implemented a `before_send` filter that suppresses known operational exceptions and logger-specific noise while still reporting genuine errors.", "body_md": "A clean Sentry inbox is a load-bearing developer tool. The day yours starts showing 4,000 events for things that aren't bugs, you stop opening it. The day after that, you miss the real bug.\n\nWe upgraded [HoneyChat](https://honeychat.bot/) — Telegram-native AI companion, ~300 DAU — from Sentry SDK 1.x to 2.x and that's what happened. The SDK gained a useful new behavior: it auto-enables a set of integrations whenever it detects the relevant library imported. **Loguru, OpenAI, SQLAlchemy, asyncpg, Redis, httpx** — all on by default in 2.x. No more `integrations=[...]`\n\nboilerplate.\n\nThis is great when those integrations capture only real errors. They don't.\n\n**HoneyChat backend stack (for context):**\n\n`aiogram`\n\nTelegram polling bot (`bot/main.py`\n\n)`api/main.py`\n\n, `uvicorn --workers 4`\n\n)`llm`\n\n, `images`\n\n, `gifs`\n\n, `voice`\n\n(`workers/tasks.py`\n\n)`gen_worker`\n\n(image/GIF generation queue)`openai`\n\nPython SDK (`base_url`\n\nswapped to `https://openrouter.ai/api/v1`\n\n) — so `openai.*`\n\nexception types fire on OpenRouter responses tooThat stack imports every library the Sentry 2.x auto-integration looks for. They all turn on.\n\nWithin a day of the upgrade:\n\n`logger.error(\"…\")`\n\nfrom Loguru`error`\n\n-level `openai.RateLimitError`\n\nand `openai.APIConnectionError`\n\n`tenacity`\n\nretries. Not bugs.`asyncpg`\n\n/SQLAlchemy pool race`bot`\n\n, `api`\n\n, `celery_worker`\n\n, `nginx`\n\nback-to-back during a full release; pool reconnects produce a brief flurry of these. Not bugs.`ConnectionResetError`\n\nReal bugs were drowning. Issue counts went from ~5/day to 4,000+.\n\nSentry SDK 2.x scans `sys.modules`\n\nat init and turns on any integration whose target library is already imported. The relevant docs page lists them. Three matter most for a typical Python service:\n\n`LoguruIntegration`\n\n— captures Loguru records at `ERROR`\n\nand above.`OpenAIIntegration`\n\n— captures all `openai.OpenAIError`\n\nraises (which, for us, includes everything OpenRouter ever returns through the OpenAI SDK).`SqlalchemyIntegration`\n\n— captures slow queries, connection errors, and a few other states.You can disable individual integrations:\n\n``` python\nimport sentry_sdk\nfrom sentry_sdk.integrations.loguru import LoguruIntegration\nfrom sentry_sdk.integrations.openai import OpenAIIntegration\n\nsentry_sdk.init(\n    dsn=settings.SENTRY_DSN,\n    disabled_integrations=[\n        LoguruIntegration,\n        OpenAIIntegration,\n    ],\n)\n```\n\n…but that's a blunt instrument. We *do* want LLM errors reported when they're real. We want Loguru-routed errors reported when the line that produced them is actually a bug.\n\nThe fix is a `before_send`\n\nfilter.\n\n`core/sentry_filters.py`\n\n)\n\n``` python\nimport sentry_sdk\nfrom sentry_sdk.types import Event, Hint\n\nEXPECTED_EXCEPTIONS = (\n    \"openai.RateLimitError\",\n    \"openai.APIConnectionError\",\n    \"openai.APITimeoutError\",\n    \"openai.InternalServerError\",\n    \"redis.exceptions.ConnectionError\",\n    \"redis.exceptions.TimeoutError\",\n    \"asyncpg.exceptions.ConnectionDoesNotExistError\",\n    \"asyncpg.exceptions.InterfaceError\",\n    \"sqlalchemy.exc.OperationalError\",\n)\n\nOPERATIONAL_LOGGERS = (\n    \"core.llm\",            # fallback chain, content_filter rescue, retries\n    \"core.image_gen\",      # GPU → API provider switchover\n    \"core.voice\",          # Inworld TTS → gTTS fallback\n    \"workers.gen_worker\",  # task-level fallback\n)\n\ndef before_send(event: Event, hint: Hint) -> Event | None:\n    exc_info = hint.get(\"exc_info\")\n    if exc_info:\n        exc_type = exc_info[0]\n        exc_path = f\"{exc_type.__module__}.{exc_type.__name__}\"\n        if exc_path in EXPECTED_EXCEPTIONS:\n            return None\n\n    logger_name = (event.get(\"logger\") or \"\")\n    if logger_name in OPERATIONAL_LOGGERS:\n        level = event.get(\"level\")\n        if level in (\"error\", \"warning\"):\n            return None\n\n    return event\n\nsentry_sdk.init(\n    dsn=settings.SENTRY_DSN,\n    before_send=before_send,\n    traces_sample_rate=0.0,\n    profiles_sample_rate=0.0,\n)\n```\n\nThe filter is twenty lines. The two tuples are the actual contract: *these* exceptions and *these* loggers are noise. After deploying this, Sentry inbox went from 4,000+ to ~30 events/day. The 30 included two real bugs we'd been missing.\n\nA filter is half the answer. The other half is fixing the log levels at the source. Our team now follows three rules:\n\n`logger.error(...)`\n\n`logger.warning(...)`\n\n`logger.info(...)`\n\nA normal-path \"Gemini returned content_filter, falling back to Grok 4.20\" is `info`\n\n, not `error`\n\n. The terminal might lose some red, but Sentry stops crying wolf.\n\nWhen we audited our codebase against this, we found roughly 40 `logger.error`\n\nlines in `core/llm.py`\n\n, `core/image_gen.py`\n\nand `workers/gen_worker.py`\n\nthat should have been `warning`\n\nor `info`\n\n. Fixing them at source means the `before_send`\n\nfilter doesn't need to grow indefinitely.\n\nWe considered `ignore_errors=[...]`\n\non `sentry_sdk.init`\n\ninstead of a `before_send`\n\n. The problem is that `ignore_errors`\n\nonly matches by exception type *name*, not module path. `ConnectionError`\n\nis ambiguous (Redis vs httpx vs asyncpg — all have one). The fully-qualified path check in `before_send`\n\nis more precise.\n\nWe also considered turning the integrations off entirely. The risk is losing visibility into real LLM and DB errors — when there's a real bug in the LLM path, the `OpenAIIntegration`\n\n's stack-trace enrichment is genuinely useful. Keeping the integrations on and filtering precisely was the better trade.\n\n`before_send`\n\nis the right hook for noise reduction.`error`\n\ndoesn't mean \"Sentry-worthy\", your Sentry inbox is broken.The hardest part of this work isn't the filter — it's getting the team to agree on what `error`\n\nactually means.\n\nThis filter runs in production at ** HoneyChat** — Telegram-native AI companion bot. Canonical version:\n\n— *HoneyChat Engineering*\n\n`disabled_integrations`\n\n.`before_send`\n\nfiltering`None`\n\nto drop, mutate to scrub.`base_url`\n\nsetup with OpenAI SDK`openai.*`\n\nexception types fire on OpenRouter responses.", "url": "https://wpnews.pro/news/sentry-sdk-2-x-auto-integrations-flood-your-inbox-here-s-the-filter", "canonical_source": "https://dev.to/sm1ck/sentry-sdk-2x-auto-integrations-flood-your-inbox-heres-the-filter-2b24", "published_at": "2026-06-03 20:12:49+00:00", "updated_at": "2026-06-03 20:41:46.979826+00:00", "lang": "en", "topics": ["ai-tools", "ai-products", "ai-infrastructure"], "entities": ["Sentry", "HoneyChat", "Loguru", "OpenAI", "SQLAlchemy", "asyncpg", "Redis", "httpx"], "alternates": {"html": "https://wpnews.pro/news/sentry-sdk-2-x-auto-integrations-flood-your-inbox-here-s-the-filter", "markdown": "https://wpnews.pro/news/sentry-sdk-2-x-auto-integrations-flood-your-inbox-here-s-the-filter.md", "text": "https://wpnews.pro/news/sentry-sdk-2-x-auto-integrations-flood-your-inbox-here-s-the-filter.txt", "jsonld": "https://wpnews.pro/news/sentry-sdk-2-x-auto-integrations-flood-your-inbox-here-s-the-filter.jsonld"}}