Changing an unhandled exception to a handled one in a finally block <p>Consider this program:</p> <pre><code>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 { } </code></pre> <p>Here, an exception of type <code>A</code> is thrown for which there is no handler. In the <code>finally</code> block, an exception of type <code>B</code> is thrown for which there is a handler. Normally, exceptions thrown in <code>finally</code> blocks win, but it's different for unhandled exceptions.</p> <p>When debugging, the debugger stops execution when <code>A</code> is thrown, and does not allow the <code>finally</code> block to be executed.</p> <p>When not debugging (running it stand-alone from a command prompt), a message is shown (printed, and a crash dialog) about an unhandled exception, but after that, "All done!" does get printed.</p> <p>When adding a top-level exception handler that does nothing more than rethrow the caught exception, all is well: there are no unexpected messages, and "All done!" is printed.</p> <p>I understand how this is happening: the determination of whether an exception has a handler happens before any <code>finally</code> blocks get executed. This is generally desirable, and the current behaviour makes sense. <code>finally</code> blocks should generally not be throwing exceptions anyway.</p> <p>But <a href="http://stackoverflow.com/questions/2911215/what-happens-if-a-finally-block-throws-an-exception">this other Stack Overflow question</a> cites the C# language specification and claims that the <code>finally</code> block is required to override the <code>A</code> exception. Reading the specification, I agree that that is exactly what it requires:</p> <blockquote> <ul> <li>In the current function member, each <code>try</code> statement that encloses the throw point is examined. For each statement <code>S</code>, starting with the innermost try statement and ending with the outermost try statement, the following steps are evaluated: <ul> <li>If the <code>try</code> block of <code>S</code> encloses the throw point and if S has one or more <code>catch</code> clauses, the catch clauses are examined [...]</li> <li>Otherwise, if the <code>try</code> block or a <code>catch</code> block of <code>S</code> encloses the throw point and if <code>S</code> has a <code>finally</code> block, control is transferred to the <code>finally</code> block. If the <code>finally</code> block throws another exception, processing of the current exception is terminated. Otherwise, when control reaches the end point of the <code>finally</code> block, processing of the current exception is continued.</li> </ul></li> <li>If an exception handler was not located in the current function invocation, the function invocation is terminated, and one of the following occurs: <ul> <li>[...]</li> </ul></li> <li>If the exception processing terminates all function member invocations in the current thread, indicating that the thread has no handler for the exception, then the thread is itself terminated. The impact of such termination is implementation-defined.</li> </ul> </blockquote> <p>An exception isn't considered unhandled, according to my reading of the spec, until <em>after</em> all function invocations have been terminated, and function invocations aren't terminated until the <code>finally</code> handlers have executed.</p> <p>Am I missing something here, or is Microsoft's implementation of C# inconsistent with their own specification?</p>