Keep HttpEventTrigger asset watchers polling after a failed request - #72376
Open
rjgoyln wants to merge 3 commits into
Open
Keep HttpEventTrigger asset watchers polling after a failed request#72376rjgoyln wants to merge 3 commits into
rjgoyln wants to merge 3 commits into
Conversation
rjgoyln
force-pushed
the
fix/http-event-trigger-swallowed-errors
branch
from
September 2, 2026 07:45
37cf0ab to
8a55e8c
Compare
An asset watcher that gives up on its first transient error is not watching anything, and a failure reported as a bare str(e) leaves no way to tell a 503 apart from a broken response_check callable. Because the exception was swallowed rather than raised, the triggerer had nothing to record either, so the traceback was lost at both layers. Retrying forever is the opposite failure mode, so the retry gives up after a bounded number of consecutive failures and lets the error reach the triggerer.
rjgoyln
force-pushed
the
fix/http-event-trigger-swallowed-errors
branch
from
September 2, 2026 11:37
8a55e8c to
27f8867
Compare
A watcher riding out a flaky endpoint wrote a full traceback for every failed poll, while the escalation itself carried none of its own. The triggerer already routes its own record into the trigger's log, so the volume and the emphasis were both backwards. The effective failure tolerance is the cap times poll_interval rather than a fixed duration, which the parameter documentation now says.
The count alone does not tell a reader how long a watcher keeps trying, and describing it as the number of failures "tolerated" read one poll off from what the code does.
rjgoyln
marked this pull request as ready for review
September 2, 2026 13:18
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.
Summary
HttpEventTriggerwrapped its whole poll loop in oneexcept Exceptionthat loggedstr(e)and returned, so any error — a 503, a connection reset, a brokenresponse_check_path— ended the generator. The watcher stopped firing even when the next poll would have succeeded,poll_intervalwas skipped because the sleep only sat on the success path, and the cause survived as a bare message with no type or traceback, leaving the triggerer nothing to record either.Retrying forever is the opposite failure mode, so the retry gives up after
max_consecutive_failuresconsecutive failures and raises. The triggerer records the traceback and recreates the watcher, while anything deferred on the trigger fails instead of hanging. The default of 10 is chosen against the defaultpoll_intervalof 60 seconds — roughly ten minutes of continuous failure before escalating, long enough to ride out an outage and short enough that a misconfigured watcher surfaces the same day. Effective tolerance is that product rather than the count, which the parameter documentation now states.The
exceptstays broad deliberately:response_checkis arbitrary user code, so aKeyErroron an unexpected payload is as likely to be transient as a 503, and the cap bounds the genuinely permanent case. Cancellation is unaffected —CancelledErrorandGeneratorExitareBaseException, and the backoff sleep sits outside thetry.Before / after
Both versions of
run()driven through the same scenarios withasyncio.sleepstubbed:poll_intervalapartresponse_checkraisesCancelledErrorpropagatesTests
test_trigger_on_post_with_datarelied on the swallowed exception to end the generator, so it now drives one successful poll instead.Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Opus 5) following the guidelines