In short, I've written an error handler controller that has a "HandleError" action that handles all http errors that I care to handle.
For a few reasons (outlined in this answer), I'm catching http errors in two places. One is a global Application_EndRequest
method (managed pipeline) and the other is via the <httpErrors>
section in the web config (native custom errors module).
If you're wondering why I need the <httpErrors>
section, it's because certain responses aren't always caught by the managed pipeline, for example the StaticFile
handler catches all urls like ".html,.txt" and will not trigger MVC code.
My controller action looks close to this
public ActionResult HandleError(int statusCode = 0, Exception exception = null)
{
string responseProcessed = Request.Headers.Get("__p__");
if (responseProcessed == null)
{
Request.Headers.Add("__p__", "1");
switch (statusCode)
{
case 401:
return Unauthorized();
case 403:
return Forbidden();
case 404:
return NotFound();
case 500:
return InternalError(exception);
default:
return UnhandledError(exception, statusCode);
}
}
else
{
return null;
}
}
My web.config httpErrors section is currently
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404"/>
<error statusCode="404" path="/Errors/HandleError?statusCode=404" responseMode="ExecuteURL"/>
</httpErrors>
Problem
The problem is, the HandleError
method is called twice per 404 response because it first hits the custom errors module (specified via the web.config) and then my Application_EndRequest
hook catches the 404 which also triggers my action.
Question
The question is, how can I make my HandleError
action do nothing to the response instead of replacing it with a blank response (which is what happens when you return null in an action).
Note
Please note that I am aware that I can make my custom 404 error (in web.config) point to my NotFound
action explicitly and just return the view each time even though it gets called twice. There is logic (logging, etc) that still needs to only run once and I think it's better design to have it all point to the HandleError
method instead to keep repetitive checking logic down and to only runs the action once.