Reputation: 7389
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.
Upvotes: 11
Views: 6253
Reputation: 281525
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.
Upvotes: 18
Reputation: 12399
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.
Upvotes: 2
Reputation: 131112
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:
Upvotes: 3
Reputation: 40336
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;
}
}
}
Upvotes: 9