23

How can I get a dump of all local & session variables when an exception occurs? I was thinking of writing some sort of reflection based function that would interrogate the calling function & create a dump of variables & values.

Is there an existing library that I can use?

UPDATE

After speaking to a colleague, I was pointed to AOP or Aspect Oriented Programming. Here is what I understand ... Using AOP, one would simple decorate the methods & classes with certain attributes. AOP framework then injects code in or around these classes & methods. There are two separate kinds of framework, one that injects code & then compiles the assembly & the second simply uses reflection & traps the call which you have decorated and wraps whatever code around the method at runtime.

I hope all that makes sense. I will be doing more research on this & post my approach.

Thanks guys ...

Skadoosh
  • 2,575
  • 8
  • 40
  • 53

3 Answers3

14

I'm not sure if this is what you're looking for. But if you're in a catch-block you can get all fields and properties of this class in the following way:

try
{
    double d = 1 / 0;
}
catch (Exception ex)
{
    var trace = new System.Diagnostics.StackTrace();
    var frame = trace.GetFrame(1);
    var methodName = frame.GetMethod().Name;
    var properties = this.GetType().GetProperties();
    var fields = this.GetType().GetFields(); // public fields
    // for example:
    foreach (var prop in properties)
    {
        var value = prop.GetValue(this, null);
    }
    foreach (var field in fields)
    {
        var value = field.GetValue(this);
    }
    foreach (string key in Session) 
    {
        var value = Session[key];
    }
}

I've showed how to get the method name where the exception occured only for the sake of completeness.

With BindingFlags you can specify constraints, for example that you only want properties of this class and not from inherited:

Using GetProperties() with BindingFlags.DeclaredOnly in .NET Reflection

Of course the above should give you only a starting-point how to do it manually and you should encapsulate all into classes. I've never used it myself so it's untested.

Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • 1
    `this.GetType().GetProperties()` is giving a list of 150 properties and i have 1 property in my class. Why ? – Pankaj Mar 20 '12 at 15:14
  • I mean how will you distinguish which is the culprit from among 150 properties ? – Pankaj Mar 20 '12 at 15:19
  • @PankajGarg: I don't know whether the OP wants these 150 properties or not. You can always specify BindingFlags. – Tim Schmelter Mar 20 '12 at 15:28
  • This is a wrong concept. No need to use try catch specifically for logging. just use Application error events and log message here. As on error Global application level event comes into visibility . – Pankaj Mar 20 '12 at 16:19
  • 1
    @PankajGarg: Where has the OP mentioned that he wants a global error-logging functionality? Maybe he needs to get all variable values only in specific cases(classes,methods,pages,...) where an exception is raised. I think you're mixing different use-cases and reading something into the OP's requirement. – Tim Schmelter Mar 20 '12 at 16:55
  • Try catch take extra execution time and results in increase in access time. In case of error comes why don;t you put the necessary code in OnError Override of Application level OnError handler? These are inbuilt functionality. If OP is **interrogating the calling function** definitely OP will like to put it in Jail(File System/Database in the form of logging) – Pankaj Mar 20 '12 at 17:01
  • @PankajGarg: You don't get my point. First: we both don't know what OP actually needs! Second: to log all variables on specific exceptions under certain circumstances is a legit requirement. Where is the extra time when the exception already is raised? I think you misunderstood my answer as an advice how to log variables via exceptions, aren't you? The `OnError` events would not know anything of the object inside the class where the exception was raised. – Tim Schmelter Mar 20 '12 at 17:14
  • **The OnError events would not know anything of the objects inside the class where the exception was raised.** Try my answer. Please don't forget to upvote. :) ha ha ha ha – Pankaj Mar 20 '12 at 17:16
  • Another point: How would you handle the case that he wants to analyze these variables(maybe log) but not throw up the stacktrace. Then your OnError would not even be triggered. **Edit**: How does your answer show what value variable `xyz` has when the exception was raised? You don't have an instance of that class. But exactly this is what the OP wanted to know. He don't need the exception but **all conditions of all related objects at the time it was raised**. – Tim Schmelter Mar 20 '12 at 17:20
  • **Then your OnError would not even be triggered.** Once exception comes, it becomes ASp.net's job to trigger so don't worry. **How would you handle the case that he wants to analyze these variables(maybe log)** I can make OP understand better approach. Well, variables cannot be captured but other information like assembly/Function Names/Error message/Complete stack Trace can be find out in my answer. – Pankaj Mar 20 '12 at 17:26
  • @PankajGarg: Please reread the question(and my last comment, you've left out the important "but not throw up the stacktrace") and you'll see that the topic is not error logging. Consider the case that you're doing some complex things in a loop and under certain circumstances you're getting wrong results or an exception. but you don't want to leave the loop and method but go on after the exception was analyzed(and maybe the result logged). – Tim Schmelter Mar 20 '12 at 17:29
  • OP is saying **How can I get a dump of all local & session variables when an exception occurs?** now you can better understand this sentence. – Pankaj Mar 20 '12 at 17:33
  • Reread the question and if this would be the situation as you mentioned in you last comment. Then everything is in hand. Why OP is looking for reflection ? Just Think about it. – Pankaj Mar 20 '12 at 17:36
1

You should not use Exception handling in Try Catch form. Rather, it should be

  1. Page Level Error
  2. Application Level error

Suppose You have a Presentation Layer and a Business Logic Layer/DataAccess Layer.

Upon facing the error in say Business Logic, it will move directly to Glogal.asax.cs file under Application_Error Event without going back to the calling function. Here you can log the error message like below....

HttpContext.Current.Server.GetLastError().InnerException.StackTrace
HttpContext.Current.Server.GetLastError().InnerException.Message
HttpContext.Current.Server.GetLastError().InnerException.Source
HttpContext.Current.Server.GetLastError().InnerException.TargetSite.DeclaringType.FullName
HttpContext.Current.Server.GetLastError().InnerException.TargetSite.DeclaringType.Name
HttpContext.Current.Server.GetLastError().InnerException.TargetSite.DeclaringType.Namespace

In case of page level error, Priority is the Page OnError Override and finally the Application Level error event. here also you can log errors.

I will prefer Application_error handler because If you have 20 modules and a situation come when you need to create baseclass for each module. It is not good to make code redundancy.

Now in the Web Config you can write code to redirect the user on some default page like below.

<customErrors defaultRedirect="ErrorPage.htm" mode="On">
   <error statusCode="404" redirect="ErrorPageNotFound.htm"/>
</customErrors>
Pankaj
  • 9,749
  • 32
  • 139
  • 283
0

This is a question asked ad nauseum on Stack Overflow, although phrased differently. In one thread, the answer was to use PostSharp. As others have suggested dumping the stack trace, you can do that. The easiest would be to manually dump the local variables. This can either be to Trace or you can create your own custom exception handler.

Community
  • 1
  • 1
Gregory A Beamer
  • 16,870
  • 3
  • 25
  • 32