简体   繁体   中英

How to throw/catch the inner exception from a task?

Let's say I have a simple method:

private void MyMethod()
{
    try {
        myService.Do();
    } catch (MyException ex) {}
}

I have a service that uses HttpClient , and I do:

public void Do()
{
   var response = client.GetAsync(url).Result; //Alas it's not async till now
}

And now I'm implementing a DelegatingHandler and I override SendAsync :

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    return await base.SendAsync(request, cancellationToken)
        .ContinueWith<HttpResponseMessage>(task =>
        {
            HttpResponseMessage response = task.Result;

            if (response.StatusCode == HttpStatusCode.NotFound)
            {
                throw new MyException();
            }

            return response;
        }).ConfigureAwait(false);
}

Everything works as expected until a MyException is thrown here. The exception bubbles up to the caller, however, the exception is an AggregrateException .

Is there a way to throw the actual exception itself so that no major application-wide code-change is required?

When exception is thrown in task then using Result property you will get AggregateException where the real exception is in InnerException property of this AggregateException object (your exception is wrapped by AggregateException ).

To get the true exception (unwrapped exception) you can use GetAwaiter().GetResult() :

var result = taskThatThrowsException.GetAwaiter().GetResult();

You can also use Result property but then you should specify some condition for exception handling;

try
{
    var result = taskThatThrowsException.Result;
}
catch (AggregateException ex) when (ex.InnerException is MyException myException)
{
    // use myException - it is your true unwrapped exception
}

But you should NOT block asynchronous code - you should asynchronously wait - use await and you will get your true unwrapped exception also:

var result = await taskThatThrowsException;

AggregrateException is a consolidation of many exceptions, as an async method can throw many exceptions uppon its execution .net uses this class to return all of them.

To access the inner exceptions it has a property called InnerExceptions , it's a readonly collection that contains all the thrown ones.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM