1

I am trying to understand Exception handling in C#. I have a sample program.

class Program
{
    static void Main(string[] args)
    {
        Program p = new Program();

        try
        {
            p.Method2();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Enter into Main()");
            Console.WriteLine("The original Stack Trace Line No 47 is missing in current Stack Trace.");
            Console.WriteLine("------------------------------------------------------------------------");
            Console.Write(ex.StackTrace.ToString());
            Console.ReadKey();
        }
    }

    private void Method2()
    {
        try
        {
            Method1();
        }
        catch (Exception ex)
        {
            //throw ex resets the stack trace Coming from Method 1 and propogates it to the caller(Main)
            throw;
        }
    }

    private void Method1()
    {
        try
        {
            throw new Exception("Inside Method1");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception " + ex);
            throw;
        }
    }
}

I would like to see the original stack trace line number in the main method(which I can see in the catch block of the Method1). Is this possible?

enter image description here

KiddoDeveloper
  • 568
  • 2
  • 11
  • 34
  • No. I just want to see same line number 47 in the main() catch block. – KiddoDeveloper Jan 14 '20 at 14:11
  • 1
    Unfortunately you can't without the PDB file. – Matthew Watson Jan 14 '20 at 14:13
  • Ah, I see. You basically want the second line in the picture to be (re-)written below the dashed line, right? – Corak Jan 14 '20 at 14:17
  • Yes @Corak. Throw did not override stack trace like Throw ex do. So, my question is If I am using Throw, it should also show original line number i.e. 47 – KiddoDeveloper Jan 14 '20 at 14:22
  • @MatthewWatson Can I generate PDB file in the Console App. – KiddoDeveloper Jan 14 '20 at 14:23
  • Hmm... if you keep Method2 as is, but change Method1 to only contain the line "throw [...]" then the stack trace contains that line number. - so the "problem" appears to be re-throwing in Method1. – Corak Jan 14 '20 at 14:25
  • Well, according to https://stackoverflow.com/a/17091351/1336590 you can use `System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex).Throw();` instead of just `throw;` in Method1... that way, the line 47 will show up. Not sure if that's worth the trouble, though. – Corak Jan 14 '20 at 14:37

2 Answers2

0

I'm on .NET Core, but I think it works the same for .NET Framework. I copied your code, and just added line number as comments in the interesting lines:

private void Method1()
{
    try
    {
        throw new Exception("Inside Method1"); // line 42
    }
    catch (Exception ex)
    {
        Console.WriteLine("Exception " + ex);
        throw; // line 47
    }
}

The code above print the following:

at Main.Program.Method1() in C:...\Main.cs:line 42

in both Console.WriteLine in Method1 and Main.

If I replace throw by throw ex in the catch block, then it prints:

at Main.Program.Method1() in C:...\Main.cs:line 42

in Console.WriteLine in Method1, and

at Main.Program.Method1() in C:...\Main.cs:line 47

in Console.WriteLine in Main, because the exception is rethrown, so the line number change.

All of that to say that your code works as you expect; so the code you are executing is maybe not the one you compile :-)

Guillaume S.
  • 1,515
  • 1
  • 8
  • 21
-1

You can make use of the StackTrace class to get more information like ClassName , LineNumber etc. Eg below

catch (Exception ex)
{
    // Get stack trace for the exception with source file information
    var st = new StackTrace(ex, true);
    // Get the top stack frame
    var frame = st.GetFrame(0);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();
}

Edit

An even better way to do is, create a concrete place like this where you can just pass the Exception to get all the information you need.

public static AdditionalInformation GetStackTrace(Exception exception)
        {
            var trace = new StackTrace(exception, true);
            var reflectedType = trace.GetFrame(0).GetMethod().ReflectedType;
            var additionalInformation = new AdditionalInformation();
            if (reflectedType != null)
            {
                additionalInformation = new AdditionalInformation()
                {
                    Column = trace.GetFrame(0).GetFileColumnNumber(),
                    Line = trace.GetFrame(0).GetFileLineNumber(),
                    MethodName = reflectedType.FullName,
                    File = trace.GetFrame(0).GetFileName()
                };

            }
            return additionalInformation;
        }
HariHaran
  • 3,642
  • 2
  • 16
  • 33