Consider this program:
using System; static class Program { static void Main(string[] args) { try { try { throw new A(); } finally { throw new B(); } } catch (B) { } Console.WriteLine("All done!"); } } class A : Exception { } class B : Exception { }
An exception of type A
is thrown for which there is no handler. In the finally
block, an exception of type B
selected for which there is a handler. Typically, exceptions thrown at finally
block the gain, but it is different for unhandled exceptions.
When debugging, the debugger stops execution when A
called and does not allow the execution of the finally
block.
If debugging fails (it starts autonomously from the command line), a message is displayed (printed and failure dialog) about the unhandled exception, but after that "Everything is done!" prints out.
When adding a top-level exception handler that does nothing more than reconstruct the caught exception, everything is in order: there are no unexpected messages and "Everything is done!". is printed.
I understand how this happens: determining whether an exception is thrown by the handler before any finally
blocks are executed. This is usually desirable, and current behavior makes sense. finally
blocks should not generally throw exceptions.
But this other question refers to the C # language specification and states that the finally
block is required to override exception A
Reading the specification, I agree that this is exactly what it requires:
- The current member of the function considers each
try
that spans the cast point. For each S
statement, starting with the innermost try statement and ending with the outer try statement, the following steps are evaluated:- If a
try
block from S
encloses a cast point, and if S has one or more catch
, catch conditions are considered [...] - Otherwise, if a
try
or catch
block of an S
block encloses a cast point, and if S
has a finally
block, control is passed to the finally
block. If the finally
block throws another exception, the processing of the current exception is terminated. Otherwise, when control reaches the endpoint of the finally
block, processing of the current exception continues.
- If the exception handler was not in the current function call, the function call ends and one of the following events occurs:
- If exception handling completes all calls to function members in the current thread, indicating that the thread does not have an exception handler, then the thread itself ends. The effect of such completion is determined by the implementation.
An exception is not considered unhandled according to my reading of the specification until all function calls are completed and function calls are completed until finally
handlers are executed.
Am I missing something, or is the Microsoft C # implementation not up to their own specification?
source share