4

I have tried several suggestions on how to keep the correct line number in the stack trace when throwing an exception. The most common being just catch and throw, but that doesn't work. Here are a few I've tried:

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        test();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}
private void test()
{
    try
    {
        int a = 1;
        int b = 0;
        int x = 0;
        x = a / b;
    }
    catch 
    {
        throw;
    }
}

And a few variations on the catch block.

catch (Exception)
{
    throw;
}

catch (Exception e)
{
   throw;
}

catch (Exception e)
{
    throw e;
}

All of these report error on the throw line and the message box line - never on the line that divides by 0. If I break inside the test() function, it does show the right line #, but after being thrown does not. The only way that has worked is to not have any try/catch in the test() function. But of course I want to be able to catch errors and re-throw them and keep the stack trace correct. So how is this done?

Thank you.

FirstByte
  • 563
  • 1
  • 6
  • 20
  • `throw new Exception("See InnerException", ex);` catcher can look at the InnerException property of the caught exception to see the original stacktrace etc. – 15ee8f99-57ff-4f92-890c-b56153 Sep 29 '16 at 19:31
  • http://stackoverflow.com/questions/22623/best-practices-for-catching-and-re-throwing-net-exceptions – hatchet - done with SOverflow Sep 29 '16 at 19:40
  • Actually closer to http://stackoverflow.com/questions/57383/in-c-how-can-i-rethrow-innerexception-without-losing-stack-trace ... but surprised `ExceptionDispatchInfo` is only mentioned by comment in that one @hatchet. – TylerY86 Sep 30 '16 at 01:17

3 Answers3

3

You want ExceptionDispatchInfo.Capture(ex).Throw();.

Here's why.

This might be a duplicate of this other question.

Community
  • 1
  • 1
TylerY86
  • 3,737
  • 16
  • 29
1

In release time you will not have the line number as the number of line is retrieved from the *.pdb file which contains all symbols of compilation.
So if you are planning to get the exact line number in release / production you have to copy the pdb file

BRAHIM Kamel
  • 13,492
  • 1
  • 36
  • 47
0

The simplest way is to simply remove the try catch in test. If that is not an option, as mentioned in the comment above, you can throw a new exception, passing in the old exception and look for the inner exception for actual stack trace info.

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        test();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.InnerException.ToString());
    }
}

public void test()
{
    try
    {
        int a = 1;
        int b = 0;
        int x = 0;
        x = a / b;
    }
    catch (Exception e)
    {
        throw new Exception("inner exception", e);
    }
}
Paul Tsai
  • 893
  • 6
  • 16