An unhandled exception causes the Web API service to crash when thrown in an asynchronous action

According to the documentation HttpResponseException

, web APIs are handled automatically and the web API should just return to the HttpResponseMessage

client with the appropriate one HttpStatusCode

, AND that works ... usually.

But if we throw out HttpResponseException

of the action marked async

, then it just doesn't work, it HttpResponseException

just crashes the whole service with something like "Exception was handled by user code" message. Adding a custom exclusion filter does not solve the problem because the web API does not detect the message HttpResponseException

.

Update 1 I researched further and found out that once you add a modifier await

to an action then any unhandled exception from that action will crash the web API service. And no ExceptionFilterAttributes are involved, the web API just doesn't execute them. You don't even need to throw an exception from truly asynchronous code, just add async

to the action so that all exceptions are completely unhandled.

It works fine here, the exception can be caught by some kind of exception filter:

public void Test()
{
    throw new Exception("Hello");
}

      

And this causes the service to crash:

public async void Test()
{
    throw new Exception("Hello");
}

      

Update 2 Well, it looks like everything works great if we change void

to some real type, here:

public async Task<int> Test()
{
    throw new Exception("Hello");
}

      

So, it looks like an unhandled exception from async void

calling the service fails, but async Task<SomeType>

works well, exception filters capture everything except HttpResponseException

and HttpResponseException

are handled correctly by the web API.

Looks like I was just talking to myself, but would be interested to know why exceptions in actions async void

cannot be handled correctly?

+3


source to share


1 answer


One of the reasons why you should avoid async void

is the way you handle errors.

async void

are intended to be used as event handlers. All other methods async

must be async Task

or async Task<T>

. The analogue of the async

synchronous- void

rotation method is async Task

, not async void

.



async

methods that return a task object throw an exception on that task object. Methods async void

do not have a task object, so they handle exceptions by incrementing them by the SynchronizationContext

one that was active when the method was run async void

. This emulates the behavior of event handlers.

+3


source







All Articles