Agora existe um pacote ELMAH.MVC no NuGet que inclui uma solução aprimorada da Atif e também um controlador que lida com a interface elmah no roteamento MVC (não é mais necessário usar esse axd).
A melhor solução IMHO é criar um filtro que atue no final de todos os outros filtros e registre os eventos que já foram manipulados. O módulo elmah deve cuidar de registrar os outros erros que não são tratados pelo aplicativo. Isso também permitirá que você use o monitor de integridade e todos os outros módulos que podem ser adicionados ao asp.net para examinar eventos de erro
O problema com essa solução (e com todas as aqui) ) é que, de uma maneira ou de outra, o manipulador de erros elmah está realmente lidando com o erro, ignorando o que você pode querer configurar como uma tag customError ou através do ErrorHandler ou seu próprio manipulador de erros
Eu escrevi isso olhando com refletor no 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;
}
}
Agora, na sua configuração de filtro, você deseja fazer algo assim:
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());
}
Observe que deixei um comentário lá para lembrar às pessoas que, se elas quiserem adicionar um filtro global que realmente manipulará a exceção, ela deve ocorrer ANTES deste último filtro; caso contrário, você encontrará o caso em que a exceção não tratada será ignorada pelo ElmahMVCErrorFilter porque ele não foi tratado e deve ser registrado pelo módulo Elmah, mas o próximo filtro marca a exceção como manipulada e o módulo a ignora, resultando na exceção que nunca a transforma em elmah.
Agora, verifique se as configurações de aplicativos para elmah no seu webconfig são parecidas com esta:
<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 -->
O importante aqui é "elmah.mvc.disableHandleErrorFilter", se isso for falso, ele usará o manipulador dentro de elmah.mvc que realmente tratará a exceção usando o HandleErrorHandler padrão que ignorará suas configurações de customError
Essa configuração permite que você defina suas próprias tags ErrorHandler em classes e visualizações, enquanto ainda registra esses erros através do ElmahMVCErrorFilter, adicionando uma configuração customError ao seu web.config através do módulo elmah, até mesmo escrevendo seus próprios manipuladores de erros. A única coisa que você precisa fazer é lembrar de não adicionar nenhum filtro que realmente lide com o erro antes do filtro elmah que escrevemos. E eu esqueci de mencionar: não há duplicatas no elmah.