Ahora hay un paquete ELMAH.MVC en NuGet que incluye una solución mejorada de Atif y también un controlador que maneja la interfaz elmah dentro del enrutamiento MVC (ya no es necesario usar ese axd)
La mejor solución en mi humilde opinión es crear un filtro que actúe al final de todos los demás filtros y registre los eventos que ya se han manejado. El módulo elmah debe encargarse de registrar los otros errores que la aplicación no controla. Esto también le permitirá usar el monitor de salud y todos los demás módulos que se pueden agregar a asp.net para ver los eventos de error
El problema con esa solución (y con todos los que están aquí) ) es que de una forma u otra el controlador de errores de elmah realmente está manejando el error, ignorando lo que es posible que desee configurar como una etiqueta de error personalizada o mediante ErrorHandler o su propio controlador de errores
Escribí esto mirando con reflector al ErrorHandler dentro de elmah.mvc
public class ElmahMVCErrorFilter : IExceptionFilter
{
private static ErrorFilterConfiguration _config;
public void OnException(ExceptionContext context)
{
if (context.ExceptionHandled) //The unhandled ones will be picked by the elmah module
{
var e = context.Exception;
var context2 = context.HttpContext.ApplicationInstance.Context;
//TODO: Add additional variables to context.HttpContext.Request.ServerVariables for both handled and unhandled exceptions
if ((context2 == null) || (!_RaiseErrorSignal(e, context2) && !_IsFiltered(e, context2)))
{
_LogException(e, context2);
}
}
}
private static bool _IsFiltered(System.Exception e, System.Web.HttpContext context)
{
if (_config == null)
{
_config = (context.GetSection("elmah/errorFilter") as ErrorFilterConfiguration) ?? new ErrorFilterConfiguration();
}
var context2 = new ErrorFilterModule.AssertionHelperContext((System.Exception)e, context);
return _config.Assertion.Test(context2);
}
private static void _LogException(System.Exception e, System.Web.HttpContext context)
{
ErrorLog.GetDefault((System.Web.HttpContext)context).Log(new Elmah.Error((System.Exception)e, (System.Web.HttpContext)context));
}
private static bool _RaiseErrorSignal(System.Exception e, System.Web.HttpContext context)
{
var signal = ErrorSignal.FromContext((System.Web.HttpContext)context);
if (signal == null)
{
return false;
}
signal.Raise((System.Exception)e, (System.Web.HttpContext)context);
return true;
}
}
Ahora, en su configuración de filtro, desea hacer algo como esto:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//These filters should go at the end of the pipeline, add all error handlers before
filters.Add(new ElmahMVCErrorFilter());
}
Tenga en cuenta que dejé un comentario allí para recordarle a las personas que si desean agregar un filtro global que realmente maneje la excepción, debe ir ANTES de este último filtro, de lo contrario, se encontrará con el caso en que ElmahMVCErrorFilter ignorará la excepción no controlada porque no se ha manejado y el módulo Elmah debería registrarlo, pero el siguiente filtro marca la excepción como manejada y el módulo la ignora, lo que da como resultado que la excepción nunca se convierta en elmah.
Ahora, asegúrese de que los ajustes de la aplicación para elmah en su configuración web se vean así:
<add key="elmah.mvc.disableHandler" value="false" /> <!-- This handles elmah controller pages, if disabled elmah pages will not work -->
<add key="elmah.mvc.disableHandleErrorFilter" value="true" /> <!-- This uses the default filter for elmah, set to disabled to use our own -->
<add key="elmah.mvc.requiresAuthentication" value="false" /> <!-- Manages authentication for elmah pages -->
<add key="elmah.mvc.allowedRoles" value="*" /> <!-- Manages authentication for elmah pages -->
<add key="elmah.mvc.route" value="errortracking" /> <!-- Base route for elmah pages -->
El importante aquí es "elmah.mvc.disableHandleErrorFilter", si esto es falso, usará el controlador dentro de elmah.mvc que realmente manejará la excepción al usar el HandleErrorHandler predeterminado que ignorará su configuración personalizada de error
Esta configuración le permite configurar sus propias etiquetas ErrorHandler en clases y vistas, mientras sigue registrando esos errores a través de ElmahMVCErrorFilter, agregando una configuración personalizada de error a su web.config a través del módulo elmah, incluso escribiendo sus propios controladores de errores. Lo único que debe hacer es recordar no agregar ningún filtro que realmente maneje el error antes del filtro elmah que hemos escrito. Y olvidé mencionar: no hay duplicados en elmah.