Does try/finally ignore exceptions?
-
11-09-2019 - |
Question
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.
Solution
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;
}
}
}
OTHER TIPS
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.
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:
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.