-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't reliably determine if connection was successful when using HttpClient #30896
Comments
This is similar to #15567 and related issues. Basically we need to enhance the top-level HttpRequestException and add a property that would be similar to the WebException.Status property. That property was of type WebExceptionStatus enum and made it easy to distinguish various error conditions. |
This feels related to #21965. A solution here should probably also address that issue. |
I notice that mentions OperationCanceledException - in the testing I'd done I was getting OperationCanceledException when the connection timed out, but just a regular TaskCanceledException when it timed out trying to read a response. Not really something I could rely on either way! |
I have the same error.But I publish the demo on ubuntu across docker. but it doesn't occur on window environment!! |
Duplicate of #15567 |
@wizofaus @qjw2bqn sorry for pinging you in this old discussion, but I wonder about your experience with .NET 5.0+ era error handling in |
I just tried with .NET 5.0, and with HttpClient.Timeout set to 5 seconds, HttpClient.SendAsync( ) throws a TaskCanceledException (with an inner exception of TimeoutException) if the connection is successful and the request is sent but it times out reading a response (tested with https://httpbin.org/delay/10), and exactly the same result if trying to connect to an unreachable IP address (e.g 2.2.2.2), so if anything it seems harder to distinguish now? There's no OperationCanceledException any more anyhow. However, I retried the latter without setting "HttpClient.Timeout" and it threw an HttpRequestException instead (presumably because the error happened at an OS level) - checking that the InnerException is a SocketException and that the ErrorCode is 10060 might suffice in that case but I'm not sure if it can be counted on in all scenarios. I also tried after disconnecting my wifi and got the same result except a different ErrorCode (10065). I guess I was hoping for some simple way to determine "had the HTTP connection been established", and even better, had any attempt been made to send any bytes across the wire (obviously there's no reliable way to know if they'd reached the other side). |
Thanks for the detailed answer! Summarizing the cases you mentioned:
I believe 2. and 3. are really different error cases: 2. is an actual timeout (regardless if the request would be successful without it), while 3. is a TCP-level failure, which would always happen if the host is unreachable. Distinguishing between 1. and 2. "to determine had the HTTP connection been established" might be a valid ask, though we haven't seen it coming up often. Is this needed to support troubleshooting, or does your code need to make runtime decisions after telling apart the two failure cases? If it's for troubleshooting, maybe telemetry could help you? The |
Thanks, I no longer work on the product where it was an issue, but yes, it was making runtime decisions - basically if it knew the connection (or TLS session) had never been established (and no bytes sent across the wire), there was no need to go back to the server to check what had happened (the API in question was responsible for performing financial transactions) and the error could be presented to the user immediately. If not, it was necessary to attempt to get info from the server about what had happened (and if that wasn't possible, to let the user know that the operation would be retried and/or reversed where possible). |
Thanks for the feedback, really appreciate! |
If an exception is thrown from a call to HttpClient.SendAsync( ) there's no way to be certain that the connection itself failed, vs. e.g., a timeout before trying to read the response.
While there are certain SocketException SocketError values that can only happen if the DNS lookup or connection fails, if there is a) a failure negotiating the SSL handshake or b) a timeout trying to connect, there's no reliable way to programmatically distinguish this from other possible errors.
This is important in many real world applications where if there's any possibility that the remote server did receive all or part of the request, but a network or system failure occurred after this point, it's necessary to attempt to contact that server again to determine whether it did process the request.
If the HttpClient had a way of determine how many bytes had been successfully sent to the remote server before the exception occurred, that would solve it nicely too.
The text was updated successfully, but these errors were encountered: