My goal is to create an error handling within the application that handles all managed errors, not just MVC related. So I'm not using the HandleErrorAttribute pattern because it is only for MVC errors, not other managed errors.

This works for many scenarios related to managed code, but when IIS takes over, such as bad static file call (example.com/BadFileName.gif) it will return an error from IIS that discloses server details such as local file path. This is because of the following line in the web.config:

<httpErrors errorMode="Detailed" />

But when I set errorMode to other values such as Custom, or just remove the line, my custom error handling stops functioning and the default IIS errors messages are returned for everything including managed code errors.

I've tried a number of things to get to the Custom Errors to work without this setting without any luck, including:

Setting CustomError to mode="Off"

Defining Error nodes under customError to redirect to my controllers

Defining Error nodes under httpErrors to redirect to my controllers

When I step through in debugging I can see the call to the controller, but in the end IIS sends the response instead. The error logging does get called correctly Application_Error, so the code does let application handle it to certain point.

Application Details:

ASP.NET MVC 4.0

Hosted on IIS 7.5 (Azure Web Site Preview)

Is there way not use <httpErrors errorMode="Detailed" /> and make this work?

handles all managed errors What if the exception is raised by Razer (it's configuration is wrong, assembly is missing etc). What do you expect to render your error page?
–
ta.speot.isJan 25 '13 at 23:42

If there is an error in Razor then default to an IIS error. It is a valid point since you could have a runtime error, but I've kept my error pages simple, about 3 lines of Razor code.
–
JoshJan 25 '13 at 23:59

2 Answers
2

The reason you're seeing the behaviour is probably that your Application_Error handler is correctly being invoked (and invoking your controller), but then IIS is intercepting the 500 error and displaying its own error page. (though it's also possible that your Application_Error handler is itself throwing an Exception, that's something you'll want to rule out)

Because you want to handle all errors (e.g. the static file error you mentioned), you will likely be unable to rely on either ASP.NET or ASP.NET MVC to do the initial error detection for you. Not all of the errors will come from your application!

The best thing to do is to lean on IIS 7.5's error handling as much as you can, rather than try to get involved yourself too early. Let IIS do the initial error detection for you and it's much easier.

You should then be able to ditch everything apart from the logging out of your Application_Error handler - though I think you'd be best creating your own HttpModule; setting runAllManagedModulesForAllRequests on the modules node in your web.config helps you catch errors that would otherwise slip through.

I've got this setup (though I'm personally using elmah to do the logging) running on the Azure Web Sites preview, and it's catching everything except from obviously any errors that come from failing to parse web.config.

The key seems to be the existingResponse="Replace" attribute that I was missing. Great suggestions, the only thing I'd push back on is the runAllManagedModulesForAllRequests="true" suggestion. I've read that setting hurts performance and creates a few bugs. The suggestion instead is to set preCondition="" -- downside is you have to reference each module.
–
JoshJan 31 '13 at 0:04

existingResponse="Replace" will force IIS to replace the error response even if Response.TrySkipIisCustomErrors is set to true. It is common to use TrySkipIisCustomErrors = true when returning JSON from an AJAX request... otherwise, IIS will replace JSON response with a response of it's own. Reference: Response.TrySkipIisCustomErrors not working
–
Miguel AngeloMay 13 '14 at 13:58

Interesting, but that seems to be by design. The OP wants to show the error page "for all error pages, not just MVC related". You're unlikely to want custom errors on a Web API, and in any case an AJAX client still has the error code to indicate that something has gone wrong.
–
Iain GallowayMay 13 '14 at 14:19

Question--when you use IIS to intercept the error, is there any place to log the error? I find that when I use this approach my asp.net Application_Error method is never invoked, and in my error controller "Server.GetLastError" is null.
–
Tom ReganFeb 5 at 16:43

If you want to handle this in your app you can write a custom handler or use the HandleError Attribute here is a good example of one way to approach this instead of having to use IIS as a crutch. as not all IIS host providers will allow this type of customization at the server level and IMO is a bad way to approach since it creates extra configuration at deployment time.