Skip to content

fix: harden Sentry/PostHog overload-error filters (closes TONALCOACH-1C)#343

Draft
JeffOtano wants to merge 2 commits intomainfrom
claude/wonderful-tesla-HtOfb
Draft

fix: harden Sentry/PostHog overload-error filters (closes TONALCOACH-1C)#343
JeffOtano wants to merge 2 commits intomainfrom
claude/wonderful-tesla-HtOfb

Conversation

@JeffOtano
Copy link
Copy Markdown
Owner

Summary

Reviewed open Sentry issues and found TONALCOACH-1C — 807 occurrences of "This model is currently experiencing high demand" still reaching Sentry despite sentryBeforeSend having a suppression entry for that substring. Three root-cause gaps identified and fixed:

1. sentryBeforeSend.ts — cause chain not inspected (src/lib/sentryBeforeSend.ts)

The Vercel AI SDK wraps provider errors: the outer Error carries a generic message (e.g. "Error reading UI message stream") while the Gemini-specific text lives on Error.cause. The errorMessages helper only checked the outer .message, so the suppression filter matched the generic wrapper and let the event through.

Fix: Walk the full Error.cause chain and add every ancestor's message to the candidate set.

2. sentryBeforeSend.ts — non-Error objects not handled

SDK error types that implement the Error interface structurally (without extends Error) weren't inspected, so hint.originalException instanceof Error returned false and the message was silently skipped.

Fix: Duck-type the check — if originalException is a plain object with a string .message, include that message.

3. Missing Gemini 503 variant: "model is currently overloaded"

Gemini has a second 503 overload phrasing ("The model is currently overloaded. Please try again later.") that maps to provider_overload on the backend but had no suppression entry in either sentryBeforeSend or posthogBeforeSend.

Fix: Add "model is currently overloaded" to both filter lists.

4. finalizePendingMessages now idempotent (convex/ai/resilience.ts)

When @convex-dev/agent's internal stream-error handler finalizes a message before our retry loop reaches it, the subsequent finalizeMessage call throws, aborting the loop and leaving other pending messages unprocessed.

Fix: Wrap each per-message finalizeMessage call in try/catch — the catch is intentionally silent since this is a best-effort cleanup pass on an already-failed turn. The outer safeFinalizePending still catches any remaining errors.


Test plan

  • All new Sentry suppression paths covered: cause-chain one level deep, two levels deep, non-Error object, new "model is currently overloaded" pattern, kept-real-error guard
  • posthogBeforeSend gains matching "model is currently overloaded" test
  • resilienceFinalize.test.ts adds: new overloaded → provider_overload mapping, exhaustive sanitized-code table for all transient kinds
  • CI passes (typecheck, lint, vitest)
  • Close TONALCOACH-1C in Sentry after merge

https://claude.ai/code/session_018xtWrKbmTQswzitpVKoLij


Generated by Claude Code

Three gaps let "This model is currently experiencing high demand" and
similar Gemini 503 transient errors slip through the beforeSend filters
even though they are fully handled backend-side.

1. `errorMessages` in `sentryBeforeSend.ts` did not walk the Error.cause
   chain. The Vercel AI SDK wraps provider errors: the outer Error carries
   a generic message ("Error reading UI message stream") while the
   provider-specific text lives on `Error.cause`. The filter matched the
   generic message and failed to drop the event.

   Fix: walk the full cause chain and push every ancestor message into the
   candidate set.

2. Non-Error, non-string objects with a `.message` property (SDK types
   that implement the Error interface structurally without extending Error)
   were not inspected. Duck-type the check so those objects' messages are
   also included.

3. Gemini has a second 503 phrasing — "The model is currently overloaded."
   — that maps to `provider_overload` on the backend but had no matching
   suppression entry. Add "model is currently overloaded" to both
   `sentryBeforeSend` and `posthogBeforeSend` to cover it.

Additionally, `finalizePendingMessages` in `resilience.ts` now wraps each
`finalizeMessage` mutation call in a try/catch. If `@convex-dev/agent`'s
internal stream-error handler finalizes a message before our retry loop
runs, the subsequent call would throw and abort the loop, leaving other
pending messages in the thread unprocessed. The catch is intentionally
silent — this is a best-effort cleanup pass on an already-failed turn.

Tests added: cause-chain suppression (one and two levels deep), non-Error
object suppression, new overloaded pattern, kept-real-error guard, and
sanitized-code exhaustive table in resilienceFinalize.test.ts.

Fixes TONALCOACH-1C

https://claude.ai/code/session_018xtWrKbmTQswzitpVKoLij
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8422b2ae-6e18-456b-ad6e-bed69c00709c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/wonderful-tesla-HtOfb

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants