Don't use middleware, use a request filter instead.
Middleware should be used to handle exceptions. It should have always consider the response to be complete. We have a similar middleware that logs all traffic in and out of the service. We have filters that handle exceptions and turn them into graceful responses after logging the issue.
public class GeneralExceptionFilterAttribute : ExceptionFilterAttribute {
public override void OnException(HttpActionExecutedContext context) {
FilterHandlerProvider.Instance.Handle(this, context);
}
}
I won't go into to much detail about FilterHandlerProvider.Instance, because we use a DI factory to handle different exception types. In this specific case, the Instance is set as our
GeneralExceptionFilterAttribute
.
public class GeneralExceptionFilterAttributeHandler : IHandlesFilterAttribute<GeneralExceptionFilterAttribute,
HttpActionExecutedContext> {
private readonly ILogger _logger;
public GeneralExceptionFilterAttributeHandler(ILogger logger) {
_logger = logger;
}
public void Handle(GeneralExceptionFilterAttribute filter, HttpActionExecutedContext context) {
var extraInformation = new List<object>();
#if DEBUG
Debugger.Break();
#endif
if (context.Exception is HttpResponseException responseException) {
context.Response = responseException.Response;
}
else if (context.Exception is InvalidAggregateOperationException invalidAggregateOperationException) {
extraInformation.Add(invalidAggregateOperationException.AggregateId);
if (invalidAggregateOperationException.InnerException != null) {
if (context.Exception.InnerException is ItemsNotAvailableException itemsNotAvailableException) {
extraInformation.Add(itemsNotAvailableException.Type);
}
}
}
else {
context.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
_logger.LogException(context.Exception, extraInformation.ToArray());
}
}
Our ILogger is a DI instance so you may want to do that differently.
Most importantly, any exception coming from a controller is handled, logged and a graceful response is set.
Here's some more reading on filters:
Understanding Filters in MVC[
^]
Hope that helps ^_^