2

I was trying to understand the differences between throw & throw ex. In order to assist my learning, I did some research into the theory, which led me to the following links:

Summarizing the above points the difference is:-

throw re-throws the exception that was caught, and preserves the stack trace. throw ex throws the same exception, but resets the stack trace to that method.

So I went ahead & created a demo application for the same to see the difference in action.

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        Calc c = new Calc();
        c.Test();
    }
}

class Calc
{
    public void Test()
    {
        try
        {
            int a = 10;
            int b = 10;
            int c = 10 / (a - b);
        }
        catch (Exception ex)
        {

            throw; //throw statement 
        }
    }
 }
}

This gives me the output as:-

Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero. at ConsoleApplication1.Calc.Test() in C:\kgn\personal\workspace\ConsoleApplication1\ConsoleApplication1\Program.cs:line 31 at ConsoleApplication1.Program.Main(String[] args) in C:\kgn\personal\workspace\ConsoleApplication1\ConsoleApplication1\Program.cs:line 14

Now replaced the throw with throw ex.

 class Calc
{
    public void Test()
    {
        try
        {
            int a = 10;
            int b = 10;
            int c = 10 / (a - b);
        }
        catch (Exception ex)
        {

            throw ex; // throw ex statement
        }
    }
}

This gives the output as:-

Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero. at ConsoleApplication1.Calc.Test() in C:\kgn\personal\workspace\ConsoleApplication1\ConsoleApplication1\Program.cs:line 31 at ConsoleApplication1.Program.Main(String[] args) in C:\kgn\personal\workspace\ConsoleApplication1\ConsoleApplication1\Program.cs:line 14

If I see the exception messages, they are both identical.

So where is the difference?

I agree surely there is a difference, but why am I not seeing it? What point am I missing here?

The Bearded Llama
  • 3,036
  • 4
  • 20
  • 31
Kgn-web
  • 7,047
  • 24
  • 95
  • 161
  • 1
    ``throw`` re-throws the exception caught. If your test code does the same - would it not be funny if there was a difference? Instead, try to throw another exception in the catch handler. – BitTickler Sep 11 '17 at 09:03
  • 1
    See the stack trace in *Main* to compare them. – L.B Sep 11 '17 at 09:06
  • @L.B, just checked post to your comment, they also still the identical – Kgn-web Sep 11 '17 at 09:10
  • 1
    @BitTickler - the point is, there *is* a difference between `throw;` and `throw ex;` (see questions already linked in the question) and the OP wasn't able to observe the difference in their test. – Damien_The_Unbeliever Sep 11 '17 at 09:31

1 Answers1

6

The problem that you're not seeing is that the possible throw locations you're working with are so close together as to be indistinguishable when the stack trace is collected.

Try instead:

public void Test()
{
  try
  {
    Deeper();
  }
  catch (Exception ex)
  {

    throw; //throw statement 
  }
}

private static void Deeper()
{
  int a = 10;
  int b = 10;
  int c = 10 / (a - b);
}

The throw; variant will show you Deeper in the stack trace. throw ex; will only show Test as the deepest level.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • Yes. correct. But can you please add brief detail why so?? – Kgn-web Sep 11 '17 at 09:20
  • Also I am not sure if you downvoted the question. But do you find anything wrong with my post. I read something & I tried to see it in action but when it didn't I shared with all the details. – Kgn-web Sep 11 '17 at 09:22
  • @Kgn-web - I assume the downvoters are skimming the question and assume it's asking *about* the difference between the two rather than *why* you cannot demonstrate the difference. And I tried to cover the why in my first paragraph - the location that originally threw the divide by zero and the `throw` within your `catch` are "too close" together in the IL - such that the CLR is unable to distinguish between the two locations when gathering the stack trace. By my introducing the extra method, I definitely ensure that the two locations *should* generate different stack traces. – Damien_The_Unbeliever Sep 11 '17 at 09:25