Azure / azure-functions-dotnet-worker

Azure Functions out-of-process .NET language worker
MIT License
427 stars 182 forks source link

If the Azure Function is async, all exceptions caught in middleware are AggregateException #993

Closed slogan3685 closed 1 month ago

slogan3685 commented 2 years ago

Based on the sample project I have the following middleware...

public class ExceptionHandlingMiddleware : IFunctionsWorkerMiddleware
    {
        public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
        {
            try
            {
                await next(context);
            }
            catch (Exception ex)
            {

            }
        }
    }

...function, and...

    public class Function1
    {
        [Function("Function1")]
        public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
        {
            throw new ApplicationException("from body");
        }
    }

...startup code

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(workerApplication =>
    {
        // Register our custom middlewares with the worker
        workerApplication.UseMiddleware<ExceptionHandlingMiddleware>();
    })
    .Build();

When I run this, the middleware catches an AggregateException containing the ApplicationException that I threw. Is this the expected behaviour, meaning I need to inspect the exception(s) within and decide how to handle them? Fwiw, if the function is not async then it works as I expected - the middleware catches the ApplicationException directly.

SeanFeldman commented 2 years ago

Looks similar to #912

kshyju commented 2 years ago

The current design is to throw an aggregate exception which contains the other exception which was thrown. We plan on changing the behavior in the next major version change, so that it will throw the actual exception instead of an aggregate exception.

SeanFeldman commented 1 year ago

My current workaround for now:

static Exception GetSpecificException(AggregateException exception) => 
     exception.Flatten().InnerExceptions.FirstOrDefault()?.InnerException ?? exception;
SeanFeldman commented 8 months ago

With Microsoft.Azure.Functions.Worker 1.21.0, I am seeing user code exception thrown in a trigger caught in the middleware, as expected, and no longer need the workaround.

(HTTP, both, Built-in HTTP model and ASP.NET Core integration)

I've used HTTP and ASB triggers to validate this. cc @kshyju

fabiocav commented 1 month ago

This is no longer relevant as it has been addressed in recent versions of the SDK (1.16+)