HttpClient - работа с агрегатни изключения

Здравейте, използвам HttpClient, подобен на този:

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;
    }
}

Но изпитвам трудности при работа с изключения. Добавих допълнителните блокове за улавяне, само за да опитам да хвърлям стъпка, но нито една от точките на прекъсване не е уловена в нито един от блоковете за улавяне. Осъзнавам, че при използване на Task изключението може да възникне в нишка, различна от повикващата, така че изключението е обвито в сборен контейнер, но не съм сигурен кой е най-добрият начин за справяне с тези изключения.

Например правя заявка към уеб услуга и определям невалиден параметър в заявката и се хвърля изключение. Искам да мога да уловя сборните изключения и да разгледам вътрешните изключения, за да разбера защо заявката е неуспешна и да върна приятелско съобщение.

Така че въпросът ми е какъв е най-добрият начин да уловя тези сборни изключения и да се справя с тях?


person gdp    schedule 28.06.2012    source източник


Отговори (1)


Изключението е хвърлено от 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;
    }
});

По-добре: проверете дали задачата е с грешка, преди да осъществите достъп 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;
    }
});

Ако всъщност не правите нещо в ContinueWith, можете просто да го пропуснете :

var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(...);
return client.GetStringAsync(url);
person dtb    schedule 28.06.2012
comment
Страхотно, ще го пробвам в следващия час! - person gdp; 28.06.2012
comment
Знам, че това е стар въпрос, но има ли някакъв начин да получите http кода на състоянието от aggregateexception, както можете, когато улавяте webexception? - person gdp; 16.02.2013
comment
@gdp: Да, можете да извикате .Flatten на AggregateException и след това да получите достъп до свойството InnerExceptions и да извадите WebException, съдържащо се в него. - person Jeff Fischer; 12.08.2016