static void Main(string[] args)
{
try
{
try
{
WriteLine("1 Entered try block");
throw new ArithmeticException("EXC 1 InnerTry");
}
catch (Exception e)
{
WriteLine("2 Entered inner catch block, exception:");
WriteLine(e.Message);
throw new ArithmeticException("EXC 2 InnerCatch");
}
finally
{
WriteLine("3 Entered finally block.");
throw new ArithmeticException("EXC 3 InnerFinally");
}
}
catch (Exception e)
{
WriteLine("4 Entered outer catch block, exception:");
WriteLine(e.Message);
}
}
For the above code, the output is
1 Entered try block
2 Entered inner catch block, exception:
EXC 1 InnerTry
3 Entered finally block.
4 Entered outer catch block, exception:
EXC 3 InnerFinally
Showing that the ArithmeticException("EXC 3 InnerFinally")
in some sense overwrote the ArithmeticException("EXC 2 InnerCatch")
exception.
However, in this code:
static void Main(string[] args)
{
try
{
WriteLine("1 Entered try block");
throw new ArithmeticException("EXC 1 InnerTry");
}
catch (Exception e)
{
WriteLine("2 Entered inner catch block, exception:");
WriteLine(e.Message);
throw new ArithmeticException("EXC 2 InnerCatch");
}
finally
{
WriteLine("3 Entered finally block.");
throw new ArithmeticException("EXC 3 InnerFinally");
}
}
The output is
1 Entered try block
2 Entered inner catch block, exception:
EXC 1 InnerTry
Unhandled exception. System.ArithmeticException: EXC 2 InnerCatch
at ExceptionExample.Program.Main(String[] args) in D:\csharp\ExceptionExample.cs:line 77
3 Entered finally block.
so the finally exception is essentially ignored, and no information about it is displayed.
What is the reasoning behind this behaviour, and is it not quite inconsistent? I would assume that if a finally block is actually executed (no special circumstances where it might be skipped), then it will overwrite the exception, and the program would crash due to an unhandled ArithmeticException("EXC 3 InnerFinally")
exception, but that's not the case. So what's happening? Perhaps it would help to clarify when exactly the finally blocks are executed - can we not assume that they will be executed before "stepping down" in the exception handling stack?