Problem
JsonApiExceptionFilter is applied controller-scoped via [ServiceFilter] on JsonApiController with the default Order = 0. Its else branch handles any exception (mapping unknown types to 500) and sets ExceptionHandled = true.
Because it competes at the same scope and order as user-defined exception filters, it can win the tie and run first. When it does, the app's own IExceptionFilter never runs and is silently overridden, with no warning.
Expected
A catch-all should be a last-resort fallback, not a first responder. App-defined exception filters should get first chance to handle an exception; only genuinely unhandled exceptions should fall through to the toolkit.
Suggested fix
Make the catch-all run last among exception filters (their execution order is inverted, so int.MinValue runs last):
[ServiceFilter(typeof(JsonApiExceptionFilter), Order = int.MinValue)]
public abstract class JsonApiController : ControllerBase
Non-breaking: handling of JsonApiException is unchanged; apps with no custom exception filter see no difference.
Problem
JsonApiExceptionFilteris applied controller-scoped via[ServiceFilter]onJsonApiControllerwith the defaultOrder = 0. Itselsebranch handles any exception (mapping unknown types to 500) and setsExceptionHandled = true.Because it competes at the same scope and order as user-defined exception filters, it can win the tie and run first. When it does, the app's own
IExceptionFilternever runs and is silently overridden, with no warning.Expected
A catch-all should be a last-resort fallback, not a first responder. App-defined exception filters should get first chance to handle an exception; only genuinely unhandled exceptions should fall through to the toolkit.
Suggested fix
Make the catch-all run last among exception filters (their execution order is inverted, so
int.MinValueruns last):Non-breaking: handling of
JsonApiExceptionis unchanged; apps with no custom exception filter see no difference.