Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception from Func<> not caught (async)

I'm having the following piece of code (simplified in order to make this repro). Obviously, the catch exception block will contain more logic.

I am having the following piece of code:

void Main()
{
    var result = ExecuteAction(async() =>
        {
            // Will contain real async code in production
            throw new ApplicationException("Triggered exception");
        }
    );
}

public virtual TResult ExecuteAction<TResult>(Func<TResult> func, object state = null)
{
    try
    {
        return func();
    }
    catch (Exception ex)
    {
        // This part is never executed !
        Console.WriteLine($"Exception caught with error {ex.Message}");
        return default(TResult);
    }
}

Why is the catch exception block never executed?

like image 523
Sam Vanhoutte Avatar asked Feb 01 '16 14:02

Sam Vanhoutte


People also ask

What are the errors thrown from async function?

1. Error thrown from async function is a rejected promise In the async error hanlding example, the error thrown from throw Error ("Error from Asynchronous Fn") is equivalent to: For a rejected promise wrapping an uncaught error, we have two options to handle it:

What happens when an exception is thrown from a synchronous function?

If an exception is thrown, the try...catch statement catches it. For a synchronous function in JavaScript, the error handling is pretty straightforward and easy-to-understand. In the example shown above, the error thrown from innerFn will be finally caught by try…catch statement in testFn, and the output to the console will be like the code below:

How does awaitable func work with async methods?

Here’s the async method that accepts the awaitable Func delegate: The Func accepts a string parameter (the id of the record to fetch) and returns a Task of type RecordType (a generic type parameter). In the following example, Employee will be specified for the generic type. This means when the Func is awaited, it’ll return an Employee object.

How to handle async error hanlding?

In the async error hanlding example, the error thrown from throw Error ("Error from Asynchronous Fn") is equivalent to: For a rejected promise wrapping an uncaught error, we have two options to handle it: (1) Use .catch () chain function to catch the error within the promise chain.


1 Answers

The exception is not thrown because the actual signature of func is Funk<Task> due to the method being async.

Async methods have special error handling, the exception is not raised until you await the function. If you want to support async methods you need to have a 2nd function that can handle async delegates.

void Main()
{
    //This var will be a Task<TResult>
    var resultTask = ExecuteActionAsync(async() => //This will likely not compile because there 
                                                   // is no return type for TResult to be.
        {
            // Will contain real async code in production
            throw new ApplicationException("Triggered exception");
        }
    );
    //I am only using .Result here becuse we are in Main(), 
    // if this had been any other function I would have used await.
    var result = resultTask.Result; 
}

public virtual async TResult ExecuteActionAsync<TResult>(Func<Task<TResult>> func, object state = null)
{
    try
    {
        return await func().ConfigureAwait(false); //Now func will raise the exception.
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception caught with error {ex.Message}");
        return default(TResult);
    }
}
like image 173
Scott Chamberlain Avatar answered Sep 21 '22 18:09

Scott Chamberlain