AspNetCoreOData
AspNetCoreOData copied to clipboard
'UseExceptionHandler' doesn't work with OData?
I was trying to setup my API to redirect exceptions to an exception handler controller by using app.UseExceptionHandler("/error"), however whenever an error happens, I get a 404 instead.
Why am I getting a 404? I can manually navigate to "myApiUrl/error" and hit the error controller just fine, but when the error happens inside an OData controller in the application, it does not reach the error controller and produces 404 instead.
Here is a sample of my startup:
public static void Configure(
IApplicationBuilder app,
IEdmModelProvider edmModelProvider)
{
app
.UseExceptionHandler("/error")
.UseHttpsRedirection()
.UseRouting()
.UseAuthorization()
.UseCors(builder => builder.AllowAnyHeader().AllowAnyOrigin().AllowAnyMethod())
.UseEndpoints(endpoints => endpoints.MapOData(edmModelProvider))
.UseSwagger()
.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyApi"));
}
And here is the error controller:
[ApiController]
[ApiExplorerSettings(IgnoreApi = true)]
public class ErrorController : ControllerBase
{
[Route("/error")]
public IActionResult Error() => Problem();
}
When I transfer this into a standard MVC application, it works just fine, so I suspect it must be something to do with OData that I'm missing or doesn't work properly.
@julealgon Can you share me your repro?
Hi @xuzhg I'm experiencing the same issue, repro is attached: ODataReExecute.zip
For testing, please make a GET request to https://localhost:5001/odata/Products. The ProductsController will then throw an exception, which should cause the error handling middleware to re-execute the request for /error path, and thus invoke ErrorController to produce a ProblemDetails response content (see Startup.cs for configuration).
What happens instead: The ErrorController is not triggered and an empty response is returned.
I did some digging already, and i suspect ODataEndpointRouteValueTransformer might have something to do with this. What I found out is that on the second execution HttpContext.Features<IODataFeature> is not cleared, which I think causes the controller routing to fail and ultimately leads to the error. As a workaround, I'm currently using this code after UseExceptionHandler:
app.Use((context, next) =>
{
context.Features.Set<IODataFeature?>(null);
return next();
});
To make sure the feature is cleared (see commented code in Startup.cs).
Side note: UseStatusCodePagesWithReExecute seems to suffer from the same problem.
Might be related to this (closed) ticket: https://github.com/dotnet/aspnetcore/issues/13715
Any news on this? ~~Also the error that is currently returned when using UseDeveloperExceptionPage is not very helpful, as it is basically just a empty HTTP 500~~
Also the error that is currently returned when using UseDeveloperExceptionPage is not very helpful, as it is basically just a empty HTTP 500
Interesting. I didn't notice this one. @paulkroener can you open a different issue for it so it doesn't get lost here as a comment only?
Sorry, false alarm ;-) We had a IDeveloperPageExceptionFilter running which was filtering my exception.
Close the issue if it is solved, thanks.
Close the issue if it is solved, thanks.
There is no indication that this one has been solved in the thread @Gigabyte0x1337 . What @krnrpl was referring to above is a different, unrelated problem.
@julealgon @xuzhg Good news, it looks like this issue was fixed at some point, the workaround I posted above (manually clearing IODataFeature) is no longer required 🥳
I tried updating the Microsoft.AspNetCore.OData package in the repro above to the current version 8.0.10 and the problem disappears - the error controller is now executed as it should and I get a ProblemDetails response.
Please see updated example project here: ODataReExecute_updated.zip