CORS header not being set for internal server error response ASP.NET Core 3.1

Viewed 781

Here is my CORS configuration:

services.AddCors(options =>
{
    options.AddPolicy(name: "AllowedOrigins",
        policyBuilder =>
        {
            var urls = Configuration.GetSection("Host:AllowedOrigins").Get<List<string>>();
            policyBuilder.WithOrigins(urls.ToArray())
                .AllowAnyMethod()
                .AllowAnyHeader()
                .SetIsOriginAllowed((host) => true)
                .AllowCredentials();
        });
});

And in Configure method:

app.UseRouting();

app.UseCors("AllowedOrigins");
app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

For internal server error, there are no access-control-* headers in the response. As far as I know, this issue should be fixed since ASP.NET Core 2.2.

I created an issue for ASP.NET Core 3.1 and you can track the issue.

2 Answers

You need to explicitly call app.UseExceptionHandler(...) in your startup.

If you do not, then unhandled exceptions bubble up the call stack all the way to Kestrel. And Kestrel does not call the delegates hooked up to HttpContext.Response.OnStarting(...). CorsMiddleware (and many other middleware) use OnStarting to hook into adding information to the response.

Same problem in .Net 5 WebAPI project, so I guess it was not really solved by MS by the 2022..

The issue with the default behavior in my case, was that AXIOS (front-end library) does not provide any error response details unless CORS headers are present. Not sure if it's browser issue or the library issue but regardless the solution was to include CORS in response. This also got rid of the warning in console, which might have confused people, because despite warning - the status code is still 500 (it confused me also :) ).

Anyway, after following @TylerOhlsen 's answer, here what seems to have helped:

app.UseExceptionHandler(exceptionHandlerApp =>
{
    exceptionHandlerApp.Run(async context =>
    {
        context.Response.StatusCode = StatusCodes.Status500InternalServerError;
    });
});

app.UseCors(...);

You might want to do something like:

if (!env.IsProduction())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
        });
    });
}

Some details about the UseExceptionHandler are here: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-6.0

For the practical explanation why this solution even works see the answer above/below. Thank you Tyler.

Related