I'm flabbergasted. I always thought that throw
by itself in a catch block would throw the exception at hand without altering the stack trace, but that throw ex
in a catch block would alter the stack trace to show the exception originating at the location of the statement.
Take the following two blocks of code. I would expect the output to be subtly different because one uses throw
and the other uses throw ex
, but the output is identical between the two, and the actual source line that incited the initial exception is lost in both cases, which seems terrible to me. What am I missing?
This first example behaves as I would expect:
using System;
public class Program
{
public static void Main()
{
try
{
DummyWork();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private static void DummyWork()
{
try
{
throw new Exception("dummy");
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw ex; // I would expect to lose the information about the inciting line 5 above this one in this case.... and I do.
}
}
}
This second example behaves identical to the first, but I DO NOT expect that:
using System;
public class Program
{
public static void Main()
{
try
{
DummyWork();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private static void DummyWork()
{
try
{
throw new Exception("dummy");
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw; // I would NOT expect to lose the information about the inciting line 5 above this one in this case.... But I do. Output is identical.
}
}
}
UPDATE: Some commenters have said they can't repro this - here is my dot fiddle (you will have to manually edit it to go back and forth between the two versions): https://dotnetfiddle.net/Mj7eK5
UPDATE #2: In answer to some commenters who have asked for the "identical" output. Here is the output from the first example:
System.Exception: dummy
at Program.DummyWork() in d:\Windows\Temp\xoyupngb.0.cs:line 21
System.Exception: dummy
at Program.DummyWork() in d:\Windows\Temp\xoyupngb.0.cs:line 26
at Program.Main() in d:\Windows\Temp\xoyupngb.0.cs:line 9
And here is the output from the second example:
System.Exception: dummy
at Program.DummyWork() in d:\Windows\Temp\jy4xgqrf.0.cs:line 21
System.Exception: dummy
at Program.DummyWork() in d:\Windows\Temp\jy4xgqrf.0.cs:line 26
at Program.Main() in d:\Windows\Temp\jy4xgqrf.0.cs:line 9
Leaving aside the insignificant temp file differences, in both cases the outer catch (the second one) is missing the line 21 of the initial throw. I would expect that in the first example throw ex
but not in the second throw
.