fix: stop the standalone GET stream reconnecting forever on empty connections#3087
Draft
heyhayes wants to merge 2 commits into
Draft
fix: stop the standalone GET stream reconnecting forever on empty connections#3087heyhayes wants to merge 2 commits into
heyhayes wants to merge 2 commits into
Conversation
Only reset the attempt counter when events were actually received during the connection. Connections that close immediately without delivering events now count toward MAX_RECONNECTION_ATTEMPTS. Github-Issue:modelcontextprotocol#1401
Transport errors that are not tied to a specific pending request (e.g., GET stream failures) were silently swallowed by the default message handler. Add a warning log so these exceptions are at least visible in logs as an observability safety net. Github-Issue: modelcontextprotocol#1401
5 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.
Summary
Split out from #2122. Since that PR was opened, its core fix — propagating an error to a waiting request when an SSE stream ends without a response — has landed upstream independently via the
_resolve_abandoned_requesthelper (introduced in #3047), which resolves an abandoned request with a synthesized error both when an id-bearing stream ends unresumably and when reconnection attempts are exhausted.This PR carries forward only the two fixes from #2122 that are not covered by that work. Relates to #1401.
What changed
Stop the standalone GET stream reconnecting forever on empty connections.
handle_get_streamreset its attempt counter to0whenever a connection ended "normally" — i.e. theasync forover the SSE events completed without raising. A server that accepts the GET but immediately closes the stream with no events hits exactly this path, so the counter never advances and the client reconnects in an unbounded loop (throttled only by the reconnect delay). The counter now resets only when events were actually received; empty connections count towardMAX_RECONNECTION_ATTEMPTS, so the loop gives up. That give-up branch was previously marked unreachable (# pragma: no cover) — it is now reachable and covered by a test.Log unhandled exceptions in the default message handler. Transport-level errors not tied to a specific pending request (e.g. a GET stream failure) reach
_default_message_handleras anExceptionitem and were silently discarded. It now logs a warning as an observability safety net.Testing
MAX_RECONNECTION_ATTEMPTSrather than reconnecting forever._default_message_handlerlogs a warning for anExceptionitem.