12

Hi i am using HttpClient similar to this:

public static Task<string> AsyncStringRequest(string url, string contentType)
{
    try
    {
        var client = new HttpClient();
        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(contentType));

        return client.GetStringAsync(url).ContinueWith(task => {
            return task.Result;
        });
    }
    catch (AggregateException ex)
    {
        throw ex;
    }
    catch (WebException ex)
    {
        throw ex;
    }       
    catch (Exception ex)
    {
        throw ex;
    }
}

But i am having difficulties dealing with exceptions. I have added the additional catch blocks just to try and step throw, but none of the break points are caught in any of the catch blocks. I realise using Task the exception could occur on a different thread than the caller so the exception is wrapped in a aggregate container, but i am not sure what the best way to deal with these exceptions is.

For example i make a request to a web service and specific an invalid parameter in the request, and an exception is thrown. I want to me able to catch the aggregate exceptions and look at the innerexceptions to work out why the request has failed and return a friendly message.

So my question is, what is the best way to catch these aggregate exceptions and deal with them?

gdp
  • 8,032
  • 10
  • 42
  • 63

1 Answers1

19

The exception is thrown by task.Result:

var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(...);
return client.GetStringAsync(url).ContinueWith(task =>
{
    try
    {
        return task.Result;
    }
    catch (AggregateException ex)
    {
        throw ex;
    }
    catch (WebException ex)
    {
        throw ex;
    }       
    catch (Exception ex)
    {
        throw ex;
    }
});

Better: check if the task faulted before accessing task.Result:

var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(...);
return client.GetStringAsync(url).ContinueWith(task =>
{
    if (task.IsFaulted)
    {
        var ex = task.Exception;
    }
    else if (task.IsCancelled)
    {
    }
    else
    {
        return task.Result;
    }
});

If you're not actually doing something in the ContinueWith, you can simply omit it:

var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(...);
return client.GetStringAsync(url);
UserControl
  • 14,766
  • 20
  • 100
  • 187
dtb
  • 213,145
  • 36
  • 401
  • 431
  • Great, i will try it out in the next hour! – gdp Jun 28 '12 at 11:13
  • 9
    I know this is a old question, but is there any way to get the http status code from from the aggregateexception, like you can when catching a webexception? – gdp Feb 16 '13 at 17:06
  • @gdp: Yes, you can call the .Flatten on the AggregateException and then access the InnerExceptions property and pull out the WebException contained within it. – Jeff Fischer Aug 11 '16 at 22:55