views:

815

answers:

4

I have a situation where I want certain code to be executed no matter what happens, but I need exceptions to also be passed on up the stack to be handled later. Is the following:


try
{
  // code
}
finally
{
  // code that must run
}

going to just ignore any exceptions, or will it pass them on up? My testing seems to show that they still get passed on up, but I want to be sure I'm not crazy.

EDIT: My question isn't about when and if the finally will execute, it's about whether exceptions still get thrown upwards, but that's been answered now.

+15  A: 

The finally code will always run, and exceptions will be passed on up, as you say. That's pretty much the point of try/finally - to have some code that will always run, even when exceptions are thrown.

Edit: This is true for any language that provides the try/finally construct, but there are caveats for some languages, as Adam points out in his comment and Sam points out in his answer.

RichieHindle
this is not really true, see related answers
Sam Saffron
I believe that Richie is correct; in a try/finally, the code inside the try block is executed, and regardless of whether an exception is thrown, the code within the finally block is executed afterwards.
snake
@snake, see my answer and the related answers, there are some edge cases where finally in C# is not going to get executed.
Sam Saffron
also what are you answering, C# Java or Javascript?
Sam Saffron
There are some edge cases in which the finally block does not run (StackOverflowException in *some* languages, process gets terminated, power cord gets pulled, etc.), but in most cases the finally block will run and then propagate the exception downwards.
Adam Rosenfield
+4  A: 

Here's a test class that shows that (1) finally runs, regardless of whether exceptions are thrown; and (2) exceptions are passed along to the caller.

public class FinallyTest extends TestCase {
    private boolean finallyWasRun = false;

    public void testFinallyRunsInNormalCase() throws Exception {
     assertFalse(finallyWasRun);
     f(false);
     assertTrue(finallyWasRun);
    }

    public void testFinallyRunsAndForwardsException() throws Exception {
     assertFalse(finallyWasRun);
     try {
      f(true);
      fail("expected an exception");
     } catch (Exception e) {
      assertTrue(finallyWasRun);
     }
    }

    private void f(boolean withException) throws Exception {
     try {
      if (withException)
       throw new Exception("");
     } finally {
      finallyWasRun = true;
     }
    }
}
Carl Manaster
+3  A: 

Assuming this is C#, finally will always run unless you get a StackOverflowException or a ExecutingEngineException

Additionally, asynchronous exceptions like ThreadAbortException can interrupt the flow of a finally block causing it to partially execute.

See related questions:

http://stackoverflow.com/questions/833946/in-c-will-the-finally-block-be-executed-in-a-try-catch-finally-if-an-unhandled

Sam Saffron
+2  A: 

If this is C#:

The answers here are right, the finally is run and the exceptions are "passed up". But to illustrate how easy it is to figure it out:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            throw new Exception("testing");
        }
        finally
        {
            Console.WriteLine("Finally");
        }
    }
}

When running this simple, little console application, the exception is thrown and then the finally block is executed.

marcc