Getting the Id of an error in Elmah after calling .Raise()

给你一囗甜甜゛ 提交于 2019-12-03 14:06:43
Adam Goss

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.

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.

http://code.google.com/p/elmah/issues/detail?id=148#c3 is an identical request and a proposed patch on the Elmah project site

aarondcoleman

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:

  1. Store the error using ErrorLog.Log(error) (see: Using ELMAH in a console application)
  2. Raise the error skipping the logging (SQL or otherwise)

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!