-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
Noticed in #62216
Basically, the server is gracefully closing the HTTP/2 connection with protocol error of ENHANCE_YOUR_CALM. The error in the client from reading the response stream doesn't mention that error. Instead, the error is System.IO.IOException: The response ended prematurely while waiting for the next frame from the server..
The error is technically correct, but it could be more helpful if it includes information that the server decided to proactively close the connection using GO_AWAY (or abort in HTTP/3). The protocol error is a clue to why the server decided to close the connection.
Less important, but SocketsHttpHandler could provide better error details in the exception. While "The response ended prematurely while waiting for the next frame from the server." is technically correct, reporting the ENHANCE_YOUR_CALM status from the server would make it clearer what is going on.
Agreed. When the server gracefully (i.e. not in the middle of a frame) closes the connection after a GOAWAY with an error code is received, we should fail any outstanding requests with an exception that indicates the server error from GOAWAY.
This should be done in HTTP/2 and HTTP/3.
Reproduction Steps
- Read from content response stream.
- While waiting for data, the server closes the connection with a GO_AWAY frame.
- Catch error from response stream
ReadAsync.
Expected behavior
Exception includes details about the protocol error, like SendAsync reports.
Actual behavior
IOException: The request was aborted. IOException: The response ended prematurely while waiting for the next frame from the server.", DebugException="System.IO.IOException: The request was aborted.
---> System.IO.IOException: The response ended prematurely while waiting for the next frame from the server.
at System.Net.Http.Http2Connection.g__ThrowMissingFrame|57_1()
at System.Net.Http.Http2Connection.ReadFrameAsync(Boolean initialFrame)
at System.Net.Http.Http2Connection.ProcessIncomingFramesAsync()
--- End of inner exception stack trace ---
at System.Net.Http.Http2Connection.ThrowRequestAborted(Exception innerException)
at System.Net.Http.Http2Connection.Http2Stream.CheckResponseBodyState()
at System.Net.Http.Http2Connection.Http2Stream.TryReadFromBuffer(Span1 buffer, Boolean partOfSyncRead) at System.Net.Http.Http2Connection.Http2Stream.ReadDataAsync(Memory1 buffer, HttpResponseMessage responseMessage, CancellationToken cancellationToken)
at Grpc.Net.Client.StreamExtensions.ReadMessageContent(Stream responseStream, Memory`1 messageData, Int32 length, CancellationToken cancellationToken) in /var/local/git/grpc-dotnet/src/Grpc.Net.Client/Internal/StreamExtensions.cs:line 224
Regression?
No
Known Workarounds
No response
Configuration
No response
Other information
No response