When is finally run if you throw an exception from the catch block?

C#

C# Problem Overview


try {
   // Do stuff
}
catch (Exception e) {
   throw;
}
finally {
   // Clean up
}

In the above block when is the finally block called? Before the throwing of e or is finally called and then catch?

C# Solutions


Solution 1 - C#

It would be called after e is re-thrown (i.e. after the catch block is executed)

editing this 7 years later - one important note is that if e is not caught by a try/catch block further up the call stack or handled by a global exception handler, then the finally block may never execute at all.

Solution 2 - C#

Why not try it:

This is the output from executing the code below:

outer try
inner try
inner catch
inner finally
outer catch
outer finally

with code (formatted for vertical space):

static void Main() {
    try {
        Console.WriteLine("outer try");
        DoIt();
    } catch {
        Console.WriteLine("outer catch");
        // swallow
    } finally {
        Console.WriteLine("outer finally");
    }
}
static void DoIt() {
    try {
        Console.WriteLine("inner try");
        int i = 0;
        Console.WriteLine(12 / i); // oops
    } catch (Exception e) {
        Console.WriteLine("inner catch");
        throw e; // or "throw", or "throw anything"
    } finally {
        Console.WriteLine("inner finally");
    }
}

Solution 3 - C#

After reading all of the answers here it looks like the final answer is it depends:

  • If you re-throw an exception within the catch block, and that exception is caught inside of another catch block, everything executes according to the documentation.

  • However, if the re-trown exception is unhandled, the finally never executes.

I tested this code sample in VS2010 w/ C# 4.0

static void Main()
    {
        Console.WriteLine("Example 1: re-throw inside of another try block:");

        try
        {
            Console.WriteLine("--outer try");
            try
            {
                Console.WriteLine("----inner try");
                throw new Exception();
            }
            catch
            {
                Console.WriteLine("----inner catch");
                throw;
            }
            finally
            {
                Console.WriteLine("----inner finally");
            }
        }
        catch
        {
            Console.WriteLine("--outer catch");
            // swallow
        }
        finally
        {
            Console.WriteLine("--outer finally");
        }
        Console.WriteLine("Huzzah!");
        
        Console.WriteLine();
        Console.WriteLine("Example 2: re-throw outside of another try block:");
        try
        {
            Console.WriteLine("--try");
            throw new Exception();
        }
        catch
        {
            Console.WriteLine("--catch");
            throw;
        }
        finally
        {
            Console.WriteLine("--finally");
        }

        Console.ReadLine();
    }

Here is the output:

> Example 1: re-throw inside of another try block:
> --outer try
> ----inner try
> ----inner catch
> ----inner finally
> --outer catch
> --outer finally
> Huzzah!
>
> Example 2: re-throw outside of another try block:
> --try
> --catch >
> Unhandled Exception: System.Exception: Exception of type 'System.Exception' was thrown.
> at ConsoleApplication1.Program.Main() in C:\local source\ConsoleApplication1\Program.cs:line 53

Solution 4 - C#

Your example would behave identically to this code:

try {
    try {
        // Do stuff
    } catch(Exception e) {
        throw e;
    }
} finally {
    // Clean up
}

As a side note, if you really mean throw e; (that is, throw the same exception you just caught), it is much better to just do throw;, since that will preserve the original stack trace instead of creating a new one.

Solution 5 - C#

If there is an unhandled exception inside a catch handler block, the finally block gets called exactly zero times

  static void Main(string[] args)
  {
     try
     {
        Console.WriteLine("in the try");
        int d = 0;
        int k = 0 / d;
     }
     catch (Exception e)
     {
        Console.WriteLine("in the catch");
        throw;
     }
     finally
     {
        Console.WriteLine("In the finally");
     }
  }

Output:

> C:\users\administrator\documents\TestExceptionNesting\bin\Release>TestExceptionNesting.exe > > in the try > > in the catch > > Unhandled Exception: System.DivideByZeroException: Attempted to divide > by zero. at TestExceptionNesting.Program.Main(String[] args) in > C:\users\administrator\documents\TestExceptionNesting\TestExceptionNesting.cs:line 22 > > C:\users\administrator\documents\TestExceptionNesting\bin\release>

I got asked this question today at an interview and the interviewer kept going back "are you sure the finally doesn't get called?" I was uncertain if it was meant a trick question or the interviewer had something else in mind and wrote the wrong code for me to debug so I came home and tried it (build and run, no debugger interaction), just to put my mind at rest.

Solution 6 - C#

A simple way to tell also is to debug your code and notice when finally is called.

Solution 7 - C#

Testing with a C# Console Application, the finally code has been executed after the exception is thrown: The "Application Error Dialog" existed and after you chose "Close the program" option, the finally block was executed in that console window. But setting the breaking point inside the finally code block, I can never hit it. The debugger keeps stopping at the throw statement. Here is my test code:

    class Program
    {
       static void Main(string[] args)
       {
          string msg;
          Console.WriteLine(string.Format("GetRandomNuber returned: {0}{1}", GetRandomNumber(out msg), msg) == "" ? "" : "An error has occurred: " + msg);
       }

       static int GetRandomNumber(out string errorMessage)
       {
         int result = 0;
         try
         {
            errorMessage = "";
            int test = 0;
            result = 3/test;
            return result;
         }
         catch (Exception ex)
         {
            errorMessage = ex.Message;
            throw ex;

         }
         finally
         {
            Console.WriteLine("finally block!");
         }
        
       }
    }

Debugging in VS2010 - .NET Framework 4.0

Solution 8 - C#

You can do it, I have done this to ensure cleanup.

using System;
class Program
{
static void Main()
{
    FinallyThrow();
    Console.ReadLine();
}
static void FinallyThrow()
{
    // Get finally block to execute EVEN IF there is an unhandled exception
    Exception thrownEx = null;
    try
    {
        Console.WriteLine("try..");
        throw new InvalidOperationException();
    }
    catch (Exception ex)
    {
        Console.WriteLine("catch..");
        thrownEx = ex;
    }
    finally
    {
        Console.WriteLine("finally..");
        if (thrownEx != null) throw thrownEx;
    }
}
}

OUTPUT (after breaking to the unhandled exception)

try..
catch..
finally..

.Finally always run even if unhandled exception

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontgandrewsView Question on Stackoverflow
Solution 1 - C#Eric PetroeljeView Answer on Stackoverflow
Solution 2 - C#Marc GravellView Answer on Stackoverflow
Solution 3 - C#Brandon View Answer on Stackoverflow
Solution 4 - C#Daniel PrydenView Answer on Stackoverflow
Solution 5 - C#Eusebio Rufian-ZilbermannView Answer on Stackoverflow
Solution 6 - C#JonHView Answer on Stackoverflow
Solution 7 - C#Van ThiView Answer on Stackoverflow
Solution 8 - C#PaulView Answer on Stackoverflow