❔ OnActionExecuted exception filter runs before exception is thrown and is never called
I'm having a bit of an issue where I'm following the guide from https://learn.microsoft.com/en-us/aspnet/core/web-api/handle-errors?view=aspnetcore-7.0#use-exceptions-to-modify-the-response
The goal is to modify the status code when an exception is thrown, I know there are alternative ways to do this, but this is the most straightforward.
I already have an expected exception, I built the filter, then deployed it onto
builder.Services.AddControllers
options.Filters
, but it doesn't quite work as expected.
When using the debugger I noticed that the onActionExecuted is running before the exception is thrown. The exception then continues, gets thrown, but then the status code is never changed.
This was how my original implementation was supposed to behave, but after just trying to copy/paste the exact example from the docs, it didn't work either.
Could someone lead me in the right direction on figuring out why OnActionExecuted is not running for when the exception is thrown?
There is one thing to keep in mind, the app is very monorepo like, with many sub-repositories. The startup is in /api
& the exception and exception filter are declared, but used in /services
. But I don't know why this would cause any issues.Handle errors in ASP.NET Core web APIs
Learn about error handling with ASP.NET Core web APIs.
14 Replies
So I found a bit of an issue. I tried testing out throwing the error in the controller directly and it worked. However, the actual code passes through three layers.
httpService -> documentGenerator -> downloadCommand -> controller
All while the http service passes a stream down, and each layer passes the stream. So, it's almost as if /api
doesn't ever get the thrown exception in this process. Which is strange to me.
In this process, the exception is caught here, but it is never detected by asp, and never runs the exception filter. So, I'm not sure how to fix this.
(The rethrow was just to see if it did throw and was detectable here, but I'm lost on why asp doesn't detect this)@TempleOS It looks like you're handling the response a little weird here
You're using the wrong tool if it's running before the exception happens
Filters in ASP.NET Core
Learn how filters work and how to use them in ASP.NET Core.
You specifically need exception filters
How are these two things functionally different?
There's a pipeline that the filters get executed in
An exception might be an entirely different pipeline
I recommend reading that entire page to understand what tool you're using before trying to use it
You might have also configured exception handling elsewhere that prevents your filter from getting it
Do you mind explaining this a bit further. The concept of different pipelines? It seems strange that if I throw the exception directly in the controller (just immediately, not in the same fashion as shown above), that it doesn't bubble to the other filter implementation.
You might have also configured exception handling elsewhere that prevents your filter from getting itI'm kind of doubting it, but it's not impossible. It's a large app, but idk
Filters in ASP.NET Core
Learn how filters work and how to use them in ASP.NET Core.
Filters can prevent other filters from running
So by pipeline you're meaning only the filter pipeline, not some "magical term" in asp that I've never heard of
Uhh yes, I believe so
Basically if you're throwing an exception in a controller, and you've registered a filter appropriately, and the filter isn't being called
something else is handling that exception.
I believe if you enable trace-level logging
you'll see which components are being executed to handle it.
I removed the other filter as a test, no change, I modified to be an exception filter and still no change. The stack trace has some information, but still doesn't quite help me solve the core issue. The stack trace ends at the
downloadCommand
step.
So I've found a bit more information about how the app is working. There was a custom class called FileCallbackResult
inside of that class, it overwrites the ExecuteResultAsync
. This indicates that the code that I'm expecting to throw an error r.Result?.Invoke(responseBodyWriter.AsStream()) ?? Task.CompletedTask
at the result stage, but this explains why each of the other filter types would fail, and an exception filter didn't work either. The issue now is managing to get the error and handle the error before the response is sent to the client. This is an issue I am not sure how to solve.Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.