Consider this small program. Ignore, if you will, the generic catch, I've kept it brief to try and illustrate the point:
private static void Main(string[] args)
{
Try(Fail);
}
private static void Fail()
{
var x = ((string)null).Clone();
}
private static void Try(Action action)
{
try
{
action();
}
catch (Exception exc)
{
Debug.WriteLine(exc.StackTrace);
}
}
When run, the following (with some of the path info removed) is produced:
at Scratch.Program.Fail() in Program.cs:line 27
at Scratch.Program.Try(Action action) in Program.cs:line 34
My question is - why does the stack trace of the exception stop unwinding the method chain at the Try()
method? I would expect it to unwind past that to the Main()
method.
I haven't been able to find any documentation about what it is that stops exception unwinding going past the Try()
- so I'd like to understand this.
This:
try
{
action();
}
catch (Exception exc)
{
Debug.WriteLine(exc.StackTrace);
}
catches your exception inside Try
, and doesn't propagate upwards to unwind the callstack, it simply swallows the exception. Therefor, you don't see Main
as part of your stacktrace. If you want to see Main
, leave the catch
to your Main
method:
public static void Main(string[] args)
{
try
{
Try(Fail);
}
catch (Exception e)
{
}
}
And now you see:
at ConsoleApplication2.Program.Fail() in C:\Users\Yuval\documents\visual studio 14\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 25 at ConsoleApplication2.Program.Try(Action action) in C:\Users\Yuval\documents\visual studio 14\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 30 at ConsoleApplication2.Program.Main(String[] args) in C:\Users\Yuval\documents\visual studio 14\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 15
Exception.Stacktrace
calls GetStackTrace
which in the end will callnew StackTrace(this /* exception object */, true)
. When used with these parameters the stack trace will be evaluated for the point of the exception until the current method. You can check that yourself when adding
catch (Exception exc)
{
Debug.WriteLine(new StackTrace());
Debug.WriteLine(new StackTrace(exc, true));
}
The second version is the stacktrace returned by exc.StackTrace
, the first is the full stacktrace from the current method to the entry point or thread start.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With