Enrich ELMAH errors using error filtering hook
I see a lot of questions from people asking for ELMAH hooks, to be able to modify errors before written to ELMAH. While the elmah.io client supports modifying messages, ELMAH in its open source form doesn't.
With that said, there's still a way to achieve this. Let's say you want to override the user field on all errors, to a value fetched from your database. As default, ELMAH annotates all errors with the value of Thread.CurrentPrincipal.Identity.Name
, but that may not be what you want logged in all cases.
To hook into ELMAH, we'll use a hook really meant for something else: error filtering. Add a new method to Global.asax.cs
named ErrorLog_Filtering
:
void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs args)
{
}
This method is called by ELMAH before logging all exceptions. We don't have access to the actual error object logged in this method, why we cannot just set a new username. But using a small trick, we can still achieve what we are looking to do:
void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs args)
{
var httpContext = args.Context as HttpContext;
if (httpContext != null)
{
var error = new Error(args.Exception, httpContext);
error.User = GetUserFromDatabase();
ErrorLog.GetDefault(httpContext).Log(error);
args.Dismiss();
}
}
See what I did there? I simply create a new Error
object and set the User
property to the value of GetUserFromDatabase
. The method is created for the example and can be anything from an in memory variable to the result of a REST request.
When the new error is created, I call the Log
method on ELMAH to log it to the configured store. To avoid logging two errors (the original error without the user and the new error including the user), it's important to call the Dismiss
-method on the original error arguments.
That's it! All errors are now logged with a custom value in User
. The same approach can be used for setting any variable on ELMAH's Error
object.