fix(scanner,reporter): Longer inference timeout, retry Sentry reporting drops - #21
Merged
Conversation
A single OpenRouter request timeout or transient provider error used to fail the whole pattern immediately, which — since scan-and-report treats any failed pattern as fatal — took the entire CI run down with it. analyzeWithClaude now retries the inference call plus response parsing up to 3 times with backoff before giving up, via a small shared withRetry() helper that logs each failed attempt so a recovered blip still leaves a trace.
Also fixes a latent bug in the OpenRouter provider's timeout handling: AbortSignal.timeout() aborts with a DOMException, which does not extend Error, so the 'err instanceof Error' check silently skipped the intended wrapped message ('OpenRouter request timed out after Nms') and let the generic 'operation was aborted due to timeout' through instead.
Refs https://github.com/getsentry/sentry/actions/runs/31643785552, where no-class-components timed out after exactly 120s with no retry.
assertNoDrops() failed the whole run on any transport-recorded drop, including a single one-off network_error out of thousands of events — e.g. a run reporting 2887 findings failed because 1 send hit a transient connection error, even though every other event was delivered. sendItems() now retries a chunk (or single-batch window) up to REFACTOR_TASKS_SENTRY_SEND_ATTEMPTS times (default 3) when the transport records new drops since the attempt started, logging each retry. Resending re-reports every finding in the batch; duplicates land as repeat occurrences of the same fingerprinted Sentry issue, not separate issues. Only drops that survive every attempt (unrecoveredDrops) fail the run — the transport's raw cumulative tally can't tell a recovered drop from a real one, so assertNoDrops() no longer reads it directly. Verified against a real ECONNREFUSED endpoint (retries exhaust, run fails loud with the attempt count in the message) and a flaky local server that fails once then succeeds (recovers on retry, run succeeds) — both reproduce the getsentry/sentry run's 'Sentry dropped 1 of 2887 events (network_error=1)' failure and its fix. Refs https://github.com/getsentry/sentry/actions/runs/31642621319
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. Bug Fixes 🐛
🤖 This preview updates automatically when you update the PR. |
Replaces the withRetry() wrapper (and its now-unused utils/retry.ts) around analyzeWithClaude with a simpler fix: raise timeoutMs from 120s to 240s. The one failure we've observed (no-class-components in getsentry/sentry, run 31643785552) aborted at exactly the old 120s ceiling, which looks like a slow request under load rather than a hung one — headroom is the narrower fix for that evidence, and the retry wrapper was more machinery than the observed failure mode justified. The OpenRouter timeout-message classification fix (DOMException doesn't extend Error) stays: it's independently useful for whatever timeout duration is configured.
ryan953
marked this pull request as ready for review
August 12, 2026 22:28
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The last two
getsentry/sentryscheduled runs went red for two different,unrelated transient reasons after their actual bugs were fixed — an LLM
inference timeout on one pattern, and a single dropped Sentry event out of
2887 on the reporting side. Neither indicated a real problem in the repo
being scanned.
Inference timeout: raises
analyzeWithClaude's request timeout from 120sto 240s. The one failure observed (
no-class-componentsingetsentry/sentry, run31643785552)
aborted at exactly the old 120s ceiling — evidence of a slow request under
load, not a hung one — so headroom is the narrower fix; a retry loop would
have been more machinery than the evidence justified. Also fixes a latent bug
where
AbortSignal.timeout()'sDOMExceptiondoesn't extendError, so theintended "OpenRouter request timed out after Nms" message was silently
skipped in favor of the generic "operation was aborted due to timeout".
Sentry reporting drops: this one keeps its retry logic rather than a
simpler tolerance threshold, deliberately —
sentry.ts's existing commentsshow PR #15 hardened this exact path specifically to eliminate silent data
loss ("a throttled run reports 'success' while data never reached Sentry"),
and tolerating a few dropped events would reintroduce that.
FindingReporternow retries a batch up to
REFACTOR_TASKS_SENTRY_SEND_ATTEMPTStimes(default 3) when the transport records a new drop (e.g.
network_error)since that attempt started, instead of failing the run on the very first
drop regardless of cause. Only drops that survive every attempt fail the
run — verified against both an unreachable endpoint (retries exhaust, run
fails loud with the attempt count) and a local server that fails once then
recovers (retries succeed, run passes). Resending re-reports the whole batch,
including already-delivered findings; duplicates land as repeat occurrences
of the same fingerprinted issue, not separate ones.
Refs the two post-fix CI runs this responds to:
31642621319
(dropped Sentry event) and
31643785552
(inference timeout on
no-class-components).