11

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.

Motti
  • 110,860
  • 49
  • 189
  • 262
Matt H
  • 7,311
  • 5
  • 45
  • 54

4 Answers4

18

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
  • 272,464
  • 47
  • 358
  • 399
  • this is not really true, see related answers – Sam Saffron Jul 06 '09 at 23:47
  • 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 Jul 06 '09 at 23:58
  • @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 Jul 07 '09 at 00:15
  • also what are you answering, C# Java or Javascript? – Sam Saffron Jul 07 '09 at 01:45
  • 2
    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 Jul 07 '09 at 03:06
9

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
  • 39,912
  • 17
  • 102
  • 155
3

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:

In C# will the Finally block be executed in a try, catch, finally if an unhandled exception is thrown?

Community
  • 1
  • 1
Sam Saffron
  • 128,308
  • 78
  • 326
  • 506
2

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
  • 12,295
  • 7
  • 49
  • 59