Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a .net Exception how to get a stacktrace with argument values

Tags:

c#

.net

exception

I am trying to add an unhandled exception handler in .net (c#) that should be as helpfull for the 'user' as possible. The end users are mostly programers so they just need a hint of what object are they manipulating wrong.

I'm developing a windows similar to the windows XP error report when an application crashes but that gives as much imediate information as possible imediatly about the exception thrown.

While the stack trace enables me (since I have the source code) to pinpoint the source of the problem, the users dont have it and so they are lost without further information. Needless to say I have to spend lots of time supporting the tool.

There are a few system exceptions like KeyNotFoundException thrown by the Dictionary collection that really bug me since they dont include in the message the key that wasnt found. I can fill my code with tons of try catch blocks but its rather agressive and is lots more code to maintain, not to mention a ton more of strings that have to end up being localized.

Finally the question: Is there any way to obtain (at runtime) the values of the arguments of each function in the call stack trace? That alone could resolve 90% of the support calls.

like image 587
Caerbanog Avatar asked Oct 01 '08 14:10

Caerbanog


People also ask

How do I get the stack trace of an exception?

The StackTrace property is overridden in classes that require control over the stack trace content or format. By default, the stack trace is captured immediately before an exception object is thrown. Use StackTrace to get stack trace information when no exception is being thrown. Gets the Exception instance that caused the current exception.

What is the use of stacktrace property?

The StackTrace property returns the frames of the call stack that originate at the location where the exception was thrown. You can obtain information about additional frames in the call stack by creating a new instance of the System.Diagnostics.StackTrace class and using its StackTrace.ToString method.

Why does stacktrace not report all method calls in Java?

The StackTrace property may not report as many method calls as expected because of code transformations, such as inlining, that occur during optimization. The StackTrace property is overridden in classes that require control over the stack trace content or format.

Does stacktrace include the inner stacktrace from the webexception?

For example, in one place... ...and in another place... The stacktrace I print, it only start from a to b, it doesnt include the inner stacktrace from the WebException.


2 Answers

I don't think System.Diagnostics.StackFrame supplies argument information (other than the method signature).

You could instrument the troublesome calls with trace logging via AOP, or even use its exception interception features to conditionally log without having to litter your code. Have a look around http://www.postsharp.org/.

like image 79
user7375 Avatar answered Oct 13 '22 11:10

user7375


Likewise, I've not found anything to derive the parameters automatically at runtime. Instead, I've used a Visual Studio add-in to generate code that explicitly packages up the parameters, like this:

public class ExceptionHandler {     public static bool HandleException(Exception ex, IList<Param> parameters)     {         /*          * Log the exception          *           * Return true to rethrow the original exception,          * else false          */     } }  public class Param {     public string Name { get; set; }     public object Value { get; set; } }  public class MyClass {     public void RenderSomeText(int lineNumber, string text, RenderingContext context)     {         try         {             /*              * Do some work              */             throw new ApplicationException("Something bad happened");         }         catch (Exception ex)         {             if (ExceptionHandler.HandleException(                     ex,                      new List<Param>                     {                         new Param { Name = "lineNumber", Value=lineNumber },                         new Param { Name = "text", Value=text },                         new Param { Name = "context", Value=context}                     }))             {                 throw;             }         }     } } 

EDIT: or alternatively, by making the parameter to HandleException a params array:

public static bool HandleException(Exception ex, params Param[] parameters) {    ... }  ... if (ExceptionHandler.HandleException(                     ex,                      new Param { Name = "lineNumber", Value=lineNumber },                     new Param { Name = "text", Value=text },                     new Param { Name = "context", Value=context}                     )) {     throw; } ... 

It's a bit of a pain generating the extra code to explicitly pass the parameters to the exception handler, but with the use of an add-in you can at least automate it.

A custom attribute can be used to annotate any parameters that you don't want the add-in to pass to the exception handler:

public UserToken RegisterUser( string userId, [NoLog] string password ) { } 

2ND EDIT:

Mind you, I'd completely forgotten about AVICode:

http://www.avicode.com/

They use call interception techniques to provide exactly this kind of information, so it must be possible.

like image 34
Steve Morgan Avatar answered Oct 13 '22 13:10

Steve Morgan