سؤال

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).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top