fix: don't make a recoverable connection drop look like a crash#482
Open
JulienEllie wants to merge 2 commits into
Open
fix: don't make a recoverable connection drop look like a crash#482JulienEllie wants to merge 2 commits into
JulienEllie wants to merge 2 commits into
Conversation
added 2 commits
June 16, 2026 12:22
httpx.ReadError (and its NetworkError siblings) escaped the streaming retry classifier, so a socket dropped mid-stream -- a transient VPN/WiFi blip -- re-raised all the way to the REPL, which dumped a 60-line traceback that looked like a hard crash. - Broaden _RETRYABLE_EXCEPTIONS to the umbrella base classes (httpx/httpcore NetworkError + TimeoutException) so ALL transient transport failures get auto-retried, not just the handful we'd enumerated. No more whack-a-mole per subclass. - Add _render_turn_exception(): the REPL now shows a friendly one-liner for transient/connection errors and reserves the full traceback for genuine bugs. Reuses the retry classifier so the two stay in lock-step. Tests: regression coverage for ReadError/ConnectError/httpcore.ReadError in the retry classifier, plus _render_turn_exception friendly-vs-traceback behavior.
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.
What
A connection dropped mid-stream (
httpx.ReadError) escaped the streamingretry classifier and bubbled all the way up to the interactive REPL, which
dumped a ~60-line traceback. The loop technically survived, but the wall of
stack frames made a transient VPN/WiFi blip look like a hard crash.
Why it happened
_RETRYABLE_EXCEPTIONSenumerated individual transport error types:httpx.ReadError— the error you get when a socket dies mid-response — wasn'tin the list, so
should_retry_streaming()returnedFalseand the errorpropagated instead of being retried. Classic whack-a-mole: one missing mole.
The fix
Broaden the retry net to umbrella base classes.
httpx.NetworkErroris the parent of
ReadError,WriteError,ConnectError, andCloseError;httpx.TimeoutExceptioncovers every*Timeoutvariant.Listing the bases (plus the
httpcoretwins) means all transienttransport failures get the existing 3x backoff retry — no more chasing
subclasses one funeral at a time.
Stop scaring users with raw tracebacks for environment hiccups. New
_render_turn_exception()helper: transient/connection errors get afriendly one-liner ("connection blipped, re-run your prompt, your session
is intact"); genuine bugs still get the full, debuggable traceback. It
reuses the same retry classifier so the retry path and the render path
can never drift out of sync (DRY).
Tests
test_streaming_retry.pyforReadError,ConnectError, andhttpcore.ReadErrorin the classifier.test_cli_runner_turn_exception.pypins the friendly-message vs.full-traceback behavior of
_render_turn_exception.cli_runnersuites (45) stay green.Behavior change
a single friendly line, REPL keeps going.