I am using Health Monitoring for catching all errors and sending them to email. While it works in the development environment it did not when I deploy it in Prod. The only difference being the "customerrors" set to "on/off". So, I verified it again and it seems it will not log when the custom errors is set to "On/RemoteOnly". Below is part of my configuration in question.
Is there a workaround to this issue? Thanks.
<healthMonitoring enabled="true">
<eventMappings>
<clear />
<add name="All Errors" type="System.Web.Management.WebBaseErrorEvent"
startEventCode="0" endEventCode="2147483647" />
</eventMappings>
<providers>
<clear />
<add
name="SimpleMailWebEventProvider"
type="System.Web.Management.SimpleMailWebEventProvider"
to="dev@net"
from="de@net"
buffer="false"
/>
</providers>
<rules>
<clear />
<add name="All Errors Default" eventName="All Errors" provider="SimpleMailWebEventProvider"
profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" />
</rules>
</healthMonitoring>
--update This is MVC3 project
In an ASP.NET MVC 3 project you will have a global HandleError
action filter registered by default in global.asax.cs
:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
This attribute gets applied to every controller action and if customErrors
are set to On
only the custom error page is displayed and the exception that occured in a controller action is marked as handled. ASP.NET Health Monitoring doesn't see this exception anymore and can't log it.
An approach to use Health Monitoring together with the HandleError
attribute and a custom error page is described here and here and here:
You create a custom error attribute derived from HandleError
:
public class HandleErrorHealthMonitoringAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
// Do the default, i.e. show custom error page if custom errors are on
base.OnException(filterContext);
// Suppress raising the health monitoring event below if custom errors
// are off. In that case health monitoring will receive the exception
// anyway and raise the event
if (!filterContext.HttpContext.IsCustomErrorEnabled)
return;
// Raise health monitoring event
var errorEvent = new GenericWebRequestErrorEvent(
"Unhandled exception occurred.", this,
WebEventCodes.WebExtendedBase + 1, filterContext.Exception);
errorEvent.Raise();
}
}
And then register this attribute instead of default HandleError
:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorHealthMonitoringAttribute());
}
The GenericWebRequestErrorEvent
is a custom error event derived from the base WebRequestErrorEvent
. It doesn't do anything custom and only exists because WebRequestErrorEvent
doesn't have any public
constructors, so we can't use var errorEvent = new WebRequestErrorEvent(...)
:
public class GenericWebRequestErrorEvent : WebRequestErrorEvent
{
public GenericWebRequestErrorEvent(string message, object eventSource,
int eventCode, Exception exception) :
base(message, eventSource, eventCode, exception)
{
}
public GenericWebRequestErrorEvent(string message, object eventSource,
int eventCode, int eventDetailCode, Exception exception) :
base(message, eventSource, eventCode, eventDetailCode, exception)
{
}
}
Note, that you will receive an email titled with MyNamespace.GenericWebRequestErrorEvent
and not with System.Web.Management.WebRequestErrorEvent
and the event code will always be 100001
(= WebEventCodes.WebExtendedBase + 1
).