title: Odd behavior: Catching ThreadAbortException and throwing different exception
body: <p>As a result of investigating this question: <a href="https://stackoverflow.com/questions/31574378/rethrowing-exception-in-task-doesnt-make-the-task-to-go-to-faulted-state">Rethrowing exception in Task doesn't make the Task to go to faulted state</a>, I noticed some very odd behavior with the <code>ThreadAbortException</code> that I can't make sense of.</p>
  
  <p>Now, I know that <code>ThreadAbortException</code> is a very special kind of exception to begin with. And the <a href="https://msdn.microsoft.com/en-us/library/system.threading.threadabortexception(v=vs.110).aspx" rel="nofollow noreferrer">documentation</a> is pretty clear about that when it says:</p>
  
  <blockquote>
    <p><code>ThreadAbortException</code> is a special exception that can be caught, but it will automatically be raised again at the end of the <code>catch</code> block.</p>
  </blockquote>
  
  <p><strong>Scenario #1</strong>: Documented behavior.</p>
  
  <pre><code>static void Main(string[] args)
  {
      try
      {
          Thread.CurrentThread.Abort();
      }
      catch (Exception tae)
      {
          Console.WriteLine("caught exception: " + tae.GetType().Name);
      }
      Console.WriteLine("will never be reached");
  }
  </code></pre>
  
  <p>As expected, the <code>ThreadAbortException</code> is rethrown automatically, resulting in the following output:</p>
  
  <pre><code>caught exception: ThreadAbortException
  </code></pre>
  
  <p><strong>Scenario #2</strong>: Where it gets interesting is when I decide to throw a different exception in the <code>catch</code> block:</p>
  
  <pre><code>static void Main(string[] args)
  {
      try
      {
          Thread.CurrentThread.Abort();
      }
      catch (Exception tae)
      {
          Console.WriteLine("caught exception: " + tae.GetType().Name);
          throw new ApplicationException(); // will ThreadAbortException take precedence?
      }
      Console.WriteLine("will never be reached");
  }
  </code></pre>
  
  <p>In this case, I assumed that, despite the throwing of the <code>ApplicationException</code>, that the <code>ThreadAbortException</code> would be rethrown anyways to ensure that the documented behavior was preserved.  To my surprise, this is the output that resulted:</p>
  
  <pre><code>caught exception: ThreadAbortException
  
  Unhandled Exception: System.ApplicationException: Error in the application.
     at ConsoleApplication1.Program.Main(String[] args) in C:\projects\ConsoleApplication1\Program.cs:line 193
  </code></pre>
  
  <p>Did the <code>ApplicationException</code> actually <em>replace</em> and <em>prevent</em> the <code>ThreadAbortException</code> from being thrown?!?</p>
  
  <p><strong>Scenario #3</strong>: And finally, to make matters more interesting, I wrap my existing exception handling with one more <code>try-catch</code> layer:</p>
  
  <pre><code>static void Main(string[] args)
  {
      try
      {
          try
          {
              Thread.CurrentThread.Abort();
          }
          catch (Exception tae)
          {
              Console.WriteLine("caught exception: " + tae.GetType().Name);
              throw new ApplicationException();
          }
      }
      catch (Exception outerEx)
      {
          Console.WriteLine("caught outer exception: " + outerEx.GetType().Name);
      }
      Console.WriteLine("will never be reached");
  }
  </code></pre>
  
  <p>Now I'm not too sure what to expect.  Which exception will be caught in the outer <code>catch</code> block?  Will it be <code>ApplicationException</code>?  And if so, does that mean that I'll be able to swallow the exception and actually manage to print out the <code>will never be reached</code> string after all?</p>
  
  <p>This is the actual output:</p>
  
  <pre><code>caught exception: ThreadAbortException
  caught outer exception: ApplicationException
  </code></pre>
  
  <p>From the above output, it looks like the outer <code>catch</code> block does actually catch an <code>ApplicationException</code>. But by the end of <em>that</em> <code>catch</code> block, the <code>ThreadAbortException</code> now all of a sudden reappears out of thin air and gets rethrown?</p>
  
  <p><strong>Question(s)</strong>: Can someone explain and reconcile scenarios #2 and #3?  How is it that in scenario #2, it looks as though the <code>ThreadAbortException</code> is, unexpectedly, replaced by a different exception?  Yet, in scenario #3, it looks like <code>ThreadAbortException</code> was still there all along? How is this happening? Is this behavior documented somewhere?</p>