Search code examples
c#asp.net-corepipelinefluentvalidationmediatr

I can't cast Exception to ValidationException in error handling middleware


I need some help in regards of exception handling middleware in ASP.NET Core. I am using Fluent Validation to validate the input from user in a Pipeline with MediatR, the exception that gets thrown is ValidationException:

if (errors.Any())
{
    throw new ValidationException(errors);
}

It then gets caught by the mentioned middleware, but it is not ValidationException anymore. I can't cast to it. I want to retrieve errors from validation, but I can't because of that:

public async Task InvokeAsync(HttpContext context)
{
    try
    {
        await _next(context);
    }
    catch (Exception e)
    {
        await HandleExceptionAsync(context, e);
    }
}

If I change Exception e to ValidationException e it doesn't get caught at all.

And if I try this:

public async Task Invoke(HttpContext context)
{
    try
    {
        await _next(context);
    }
    catch (Exception e)
    {
        ValidationException validationException = (ValidationException)e;
        await HandleExceptionAsync(context, e);
    }
}

I get:

System.InvalidCastException: Unable to cast object of type 'System.AggregateException' to type 'FluentValidation.ValidationException'.
   at Application.Middlewares.ExceptionHandlingMiddleware.Invoke(HttpContext context) in C:\Programs\X\Application\Middleware\ExceptionHandlingMiddleware.cs:line 24
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

This is my DependencyInjection.cs:

public static IServiceCollection AddApplication(this IServiceCollection services)
{
    services.AddTransient<IPasswordHasher, PasswordHasher>();
    services.AddAutoMapper(Assembly.GetExecutingAssembly());
    services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
    services.AddMediatR(c => c.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
    services.AddScoped(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>));

    return services;
}

Everything is registered and Validation pipeline with the exception handler are working, it's just that I can't cast it to ValidationException.

Or this is not even how it should be done?


Solution

  • Exceptions thrown in tasks that aren’t awaited wrap exceptions in AggregateException and you can iterate through all the wrapped exceptions via the InnerExceptions property. Your validation exception will be in there.