As far as I can tell, there's no way to know that it's specifically a timeout that has occurred. Am I not looking in the right place, or am I missing something bigger?
string baseAddress = "http://localhost:8080/";
var client = new HttpClient()
{
BaseAddress = new Uri(baseAddress),
Timeout = TimeSpan.FromMilliseconds(1)
};
try
{
var s = client.GetAsync("").Result;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.InnerException.Message);
}
This returns:
One or more errors occurred.
A task was canceled.
From http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx
You then get access to the
Status
property, see WebExceptionStatusis what I usually do, seems to work out pretty good for me, its especially good when using proxies.
Basically, you need to catch the
OperationCanceledException
and check the state of the cancellation token that was passed toSendAsync
(orGetAsync
, or whateverHttpClient
method you're using):IsCancellationRequested
is true), it means the request really was canceledOf course, this isn't very convenient... it would be better to receive a
TimeoutException
in case of timeout. I propose a solution here based on a custom HTTP message handler: Better timeout handling with HttpClientI found that the best way to determine if the service call has timed out is to use a cancellation token and not the HttpClient's timeout property:
And then handle the CancellationException during the service call...
Of course if the timeout occurs on the service side of things, that should be able to handled by a WebException.
I am reproducing the same issue and it's really annoying. I've found these useful:
HttpClient - dealing with aggregate exceptions
Bug in HttpClient.GetAsync should throw WebException, not TaskCanceledException
Some code in case the links go nowhere:
You need to await the
GetAsync
method. It will then throw aTaskCanceledException
if it has timed out. Additionally,GetStringAsync
andGetStreamAsync
internally handle timeout, so they will NEVER throw.