views:

107

answers:

3

I am trying to get the list of calls made from the beginning of a try block to the exception. In the code below, when I fall into the Catch block, the StackTrace in the Exception object is the following : at ConsoleApplication.Program.MethodC() / at ConsoleApplication.Program.Main(String[] args). This is totally expected, but doesn't help me to get the history of calls. Does anybody have an idea on how I could do this?

    static void MethodA() { }
    static void MethodB() { }
    static void MethodC() { throw new Exception(); }

    static void Main(string[] args)
    {
        try
        {
            MethodA();
            MethodB();
            MethodC();
        }
        catch (Exception e)
        {
            // Get list of calls
            throw;
        }
    }

I was surprised to see that the StackTrace property of the Exception object isn't StackTrace object. Is there any reason for this?

In the end, the purpose of all this is simple. If an exception is thrown during the execution of the code, I want to look at the meta data (attribute) of each of the methods called.

Thanks!

+1  A: 

As I understand your question, you want to be able to know which methods was called before MethodC in your try block. I don't think you can do that without adding code to your methods.

When MethodA finishes executing, it is no longer on the stack, so there is nowhere you can get the information from. Same goes for MethodB, and only MethodC is on the stack when the Exception occurs.

driis
A: 

It seems you're not going to be able to get a stack trace for each method called with the try block unless you add custom logging code to each method. However, you can create a System.Diagnostics.StackTrace option easily from an exception simply by passing the Exception object to the constructor. This will make available all the information about the stack trace including whether the exception was thrown from MethodA/MethodB/MethodC, which might be at least somewhat helpful to you.

Example code:

static void MethodA() { }
static void MethodB() { }
static void MethodC() { throw new Exception(); }

static void Main(string[] args)
{
    try
    {
        MethodA();
        MethodB();
        MethodC();
    }
    catch (Exception e)
    {
        System.Diagnostics.StackTrace callStack = new System.Diagnostics.StackTrace(e);
        System.Diagnostics.StackFrame frame = null;
        System.Reflection.MethodBase calledMethod = null;
        System.Reflection.ParameterInfo[] passedParams = null;
        for (int x = 0; x < callStack.FrameCount; x++)
        {
            callStack.GetFrame(x);
            calledMethod = frame.GetMethod();
            passedParams = calledMethod.GetParameters();
            foreach (System.Reflection.ParameterInfo param in passedParams)
                System.Console.WriteLine(param.ToString());
        }
    }
}

(You can see this SO thread for the original answer containing the code. I've just slightly modified it.)

Hope that's at least a partial solution to your question.

Noldorin
The code doesn't work. It throws a NullRef exception on the frame.GetMethod().
Martin
That's quite strange... Inspect the other properties of the StackFrame object - it could simply be because the exception was thrown directly in the try block.
Noldorin
A: 

You can easily get a StackTrace object from anywhere in your code but as has already been pointed out you can not get the full history of method calls.

Jakob Christensen