开发者

Is there a way of showing variable values in an global ASP.Net exception?

开发者 https://www.devze.com 2023-02-06 12:20 出处:网络
I have a global error trap in the Application_Error method of Global.asax that writes a开发者_开发技巧ny unhandled exception to a log file.

I have a global error trap in the Application_Error method of Global.asax that writes a开发者_开发技巧ny unhandled exception to a log file.

Is there anyway of reporting the variable names and their values as part of the exception report?


Unless you do something really tricky with Aspect-Oriented Programming, you pretty much need to make sure that you manually introduce any relevant information into the stack trace when exceptions are thrown. For example:

public void DoSomething(int number, string name)
{
    try
    {
        ...
    } 
    catch (Exception e)
    {
        throw new Exception("Error occurred while doing something: " +
                            new {number, name}, e);
    }
}

This way, the number and name will be included in the stack trace when this exception trickles up to the top level.

Edit

After reading David Stratton's answer, I felt the need to expand on this a little. I get the sense that even some very experienced C# programmers haven't learned some of the tricks that I've learned.

First of all, I wanted to point out that the exception-handling system in .NET was designed with the idea of an InnerException specifically for this purpose (providing additional information at various points of the stack trace), and it is not at all hacky to do. However, you should definitely provide the exception as the innerException constructor parameter, rather than appending e.ToString() to the new exception's message.

Secondly, based on various comments and answers I've read on StackOverflow, as well as my own experience, it's best to:

  1. Avoid catching an exception if there's nothing specific you plan to do with it.
  2. When you catch an exception, rethrow it unless you know why the exception was thrown and you're in a scope where you know how to gracefully retreat from what you were trying to do. Simply pretending nothing went wrong is asking for more trouble down the road.
  3. When re-throwing exceptions, either just throw; to preserve the original exception's stack trace, or include the original exception as a new exception's InnerException.
  4. Consistently log exceptions that don't get re-thrown. This will generally only happen at the UI level, so you can tell the user something unexpected happened rather than allowing the program to crash.

Finally, I wanted to mention that the anonymous type declaration syntax is ideal for this kind of thing because it is very concise and it will automatically produce a string that uses the given variable names and values. For example, new {number, name}.ToString() might produce "{ number = 1, name = Test }".


We do this in some cases, but in a roundabout way. We use a try/catch at the granular level and if we want to pass the exception up to the global error handler, we build the error message. For example:

int someCounterValue = 0; string someStringValue = "Some string we want to track to send to the global error handler."

private void SomeFunction()
{
   try
   {
     someStringValue = "in the try block";
     someCounterValue = 1.5 // should thrown an exception

   }
   catch(Exception ex)
   {
     throw new Exception("Error in SomeFunction.  someStringValue = " + someStringValue + "; someCounterValue = " + someCounterValue.ToString() + "\r\nException details: " + ex.ToString());
   }
}

It's a lot of work so we really don't do this very often. Usually our error handling is better handled at the local level but in those very rate cases where you want to pass it off to the global error handler, this is about the only way we've found, since the variables would be out of scope otherwise, and therefore, inaccessible.

An easier/less hack-like option would be to set up a static class in your web app called ErrorLogger or something similar, and just handle the exceptions better locally and pass them up to the global handler ONLY when you can't do it locally.

In my opinion (and in the way we do it here by policy) a global error handler should be used to catch exceptions that you forgot to handler better at a more granular level. It should NOT just be an easy way to be lazy about proper exception handling.

Also it feels like a hack to me, so if anyone has a better option I'd like to know it, too.

0

精彩评论

暂无评论...
验证码 换一张
取 消