I\'m working on an MVC3 application and I\'m using Elmah to handle my error logging. What I want in my application is to carry the Elmah Id onto the custom error page as I will
After reading Dupin's comments it seems logical that it isn't quite possible. I tried digging around the Elmah source code and came up with a couple of alternatives that might be worth sharing.
The obvious alternative is stick with my original option of using the Logged event:
void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
string sessionId = Session.SessionID;
Session["ElmahId_" + sessionId] = args.Entry.Id;
}
For a more direct solution it is possible to manually log the error with the following:
string errorId = Elmah.ErrorLog.GetDefault(HttpContext.Current)
.Log(new Elmah.Error(filterContext.Exception));
However, using this approach won't hit your filters or mail module and so on.
After doing a bit of thinking and a little more searching, I came up with a new compromise. Still using the logged event but I've found a way to create a new unique key that can be passed to the view, by adding my own data to the exception.
string loggingKey = "ElmahId_" + Guid.NewGuid().ToString();
filterContext.Exception.Data.Add("LoggingKey", loggingKey);
This way I can pass the exception in my view model, which has this key value in the Data collection. The logged event would be changed to something like this:
void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
string key = args.Entry.Error.Exception.Data["LoggingKey"].ToString();
Session[key] = args.Entry.Id;
}
Then in the view I get the key from the model to then pull the Id from the Session collection.
http://code.google.com/p/elmah/issues/detail?id=148#c3 is an identical request and a proposed patch on the Elmah project site
Maybe not very helpful but I suspect you can't get the error id at that point and you will need to use the logged event.
When you call
Elmah.ErrorSignal.FromCurrentContext().Raise(filterContext.Exception)
You're just raising the error. Depending on how you've configured ELMAH you might be logging the error or you might just send an email or a tweet.
There's no direct link between a raised error and an Id. That will only come with logging which, if you're feeling funny, you could be doing in multiple places and so creating multiple ids.
The solution above only works only if there is a Session object (website scenario). We needed it to work in an Azure WorkerRole, or a console / desktop app type setup. This solution will also work for web and save some session memory. There isn't a perfect solution, but one that worked for us to be able to log the error and retrieve the stored ID AND fire off an email is to:
For the second part, we used the implementation of ElmahExtension given here: https://stackoverflow.com/a/2473580/476400
and REMOVED the following lines adding the logging:
(ErrorLog as IHttpModule).Init(httpApplication);
errorFilter.HookFiltering(ErrorLog); //removed!
The entire call from our client code looks like this:
ErrorLog errorLog = ErrorLog.GetDefault(null);
errorLog.ApplicationName = "YourAppName";
Error error = new Error(ex);
string errorResult = errorLog.Log(error);
Guid errorId = new Guid(errorResult);
ex.LogToElmah(); //this is just going to send the email
You might want to call that extention method something else, like RaiseToElmahNoStorage(), or something to indicate it is skipping the storage component.