Fix: swallow _receiveTask exceptions in SseClientSessionTransport.Clo…#1432
Open
xue-cai wants to merge 1 commit intomodelcontextprotocol:mainfrom
Open
Fix: swallow _receiveTask exceptions in SseClientSessionTransport.Clo…#1432xue-cai wants to merge 1 commit intomodelcontextprotocol:mainfrom
xue-cai wants to merge 1 commit intomodelcontextprotocol:mainfrom
Conversation
…seAsync
When SseClientSessionTransport.ConnectAsync fails (e.g. the SSE GET
returns 405), its catch block calls CloseAsync() before wrapping the
error in InvalidOperationException("Failed to connect transport", ex).
However, CloseAsync() awaits _receiveTask which is already faulted
with the same HttpRequestException. Since there is no try-catch around
that await, the exception propagates out of CloseAsync, out of the
catch block, and the InvalidOperationException wrapping is never
reached.
This means callers of ConnectAsync receive an unwrapped
HttpRequestException instead of the documented InvalidOperationException
wrapper, which breaks exception filtering in downstream code.
The fix wraps `await _receiveTask` in CloseAsync with a try-catch that
swallows both OperationCanceledException (normal shutdown) and other
exceptions (already observed and forwarded via
_connectionEstablished.TrySetException in ReceiveMessagesAsync).
Includes a regression test that verifies ConnectAsync throws
InvalidOperationException (not HttpRequestException) when both
Streamable HTTP POST and SSE GET fallback fail.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
…seAsync
When SseClientSessionTransport.ConnectAsync fails (e.g. the SSE GET returns 405), its catch block calls CloseAsync() before wrapping the error in InvalidOperationException("Failed to connect transport", ex).
However, CloseAsync() awaits _receiveTask which is already faulted with the same HttpRequestException. Since there is no try-catch around that await, the exception propagates out of CloseAsync, out of the catch block, and the InvalidOperationException wrapping is never reached.
This means callers of ConnectAsync receive an unwrapped HttpRequestException instead of the documented InvalidOperationException wrapper, which breaks exception filtering in downstream code.
The fix wraps
await _receiveTaskin CloseAsync with a try-catch that swallows both OperationCanceledException (normal shutdown) and other exceptions (already observed and forwarded via_connectionEstablished.TrySetException in ReceiveMessagesAsync).
Includes a regression test that verifies ConnectAsync throws InvalidOperationException (not HttpRequestException) when both Streamable HTTP POST and SSE GET fallback fail.
Motivation and Context
How Has This Been Tested?
Breaking Changes
Types of changes
Checklist
Additional context