Fail pending send_raw_request waiters when the read stream yields an exception - #3402
Conversation
…exception When a transport's read stream yields an exception item, pending send_raw_request waiters were only woken by the on_stream_exception observer (a no-op by default) -- they parked until their own timeout elapsed. Fan the raw exception out to every pending waiter and re-raise it as-is so callers see the transport's original exception type (e.g. httpx.ReadTimeout). _fan_out_closed semantics are unchanged (it now delegates to the generalized _fail_pending helper). Fixes modelcontextprotocol#1401 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
This PR has been closed automatically. This repo only keeps pull requests open when they come from a maintainer, or from a contributor a maintainer has assigned to the linked issue, and you aren't currently assigned to #1401. If a maintainer assigns you to #1401, this PR reopens on its own and there's nothing more you need to do here. Assignment is a maintainer call based on capacity; comments that only ask to be assigned don't factor in. What does help is engaging on the issue itself by confirming the repro, explaining why it matters for your use case, or describing the approach you'd take. You're welcome to keep pushing commits here (just avoid force-pushing, since GitHub can't reopen a rewritten branch), but that on its own won't get the PR reviewed or the issue assigned, and realistically most auto-closed PRs stay closed. There's no need to open a new PR either way. CONTRIBUTING.md has the full reasoning, but in short:
Maintainers: reopen, remove |
Fixes #1401
What
When a transport's read stream yields an exception item, pending
send_raw_requestwaiters were only woken by theon_stream_exceptionobserver (a no-op by default) — they parked until their own timeout elapsed. Only EOF producedCONNECTION_CLOSED._dispatch's exception branch now also fans the raw exception out to every pending waiter.send_raw_requestre-raises it as-is, so callers see the transport's original exception type (e.g.httpx.ReadTimeout) instead of a generic timeout._fan_out_closedis unchanged in behavior (delegates to a generalized_fail_pending).Why
A faulted read stream means no response can ever arrive; parking the waiters until timeout is indistinguishable from a hang. For transient faults where the stream stays open, later requests keep working.
How verified
tests/shared+tests/clientsuites pass (one pre-existing subprocess-spawn failure on this machine, reproducible on clean main — environment issue, unrelated).This contribution was developed with AI assistance (Claude Code); the approach and code were reviewed and verified by me.