views:

189

answers:

5

In a Try Catch Finally block, does the finally block always execute no matter what, or only if the catch block does not return an error?

I was under the impression that the finally block only executes if the catch block passes without errors. If the catch block is executed because of an error, shouldn't it stop execution all together and return the error message if any?

+2  A: 

the finally block executes in almost every case. That's why it's called 'finally'.

For an example, see this article on c-sharpcorner.com.

Update: It's true, if you plug the cable, melt the processor or grind the motherboard, even the most final 'finally' will not be executed.

But in almost every 'normal' scenario, i.e. wether your code throws an exception or not, the finally block will be executed. To my knowledge the only 'real' exception to this rule is a stackoverflow exception which will terminate the program w/o entering finally.

Update 2: This question was asked specifically for C#. This answer is NOT covering Java, Python, Matlab or Scheme.

Manu
<pedant>Pull out the power cable and see if it executes</pedant> :)
Mark Simpson
In Java it won't execute if there's a call to System.exit() in the try or the catch blocks.
NullUserException
In .Net, Environment.Exit() in the try or catch can prevent finally from running.
BioBuckyBall
I guess "every case" would include Java.
Jim Schubert
+12  A: 

The finally block (nearly) always executes, whether or not there was an exception.

I say nearly because there are a few cases where finally isn't guaranteed to be called:

Furthermore, even if the finally block is entered if a ThreadAbortException occurs just as the thread enters the finally block the code in the finally block will not be run.

There may be some other cases too...

Mark Byers
Uncatchable exceptions like StackOverflow and OutOfMemory could also cause it to be skipped.
Hightechrider
+1 Hightechrider: Thanks, added!
Mark Byers
A: 

The code inside the finally block gets always executed, regadless if there was an exception. By the way, I think there are already numerous threads on SO that deal with this question.

DrunkenBeard
@DrunkenBeard, sorry, my search did not return anything specific to my question that I could see from a glance.
Scott W
+1  A: 

The finally block will execute, but you'll need to be careful of exceptions within the finally block.

try {
   // some disposable method "o"
} finally {
  o.Dispose(); // if o is null, exception is thrown
   // anything after this exception will fail to execute
}
Jim Schubert
+1, but in that case a using(o) {} block would be better than a try/catch, right, since 1) setting up and tearing down a try is expensive, and2) you're guaranteed that o is not null within the using block, since if it were null you'd never get into the block in the first place? :)
Michael Blackburn
@Michael: I completely agree, but, for whatever reason, most people don't realize this is an issue. I posted this just after seeing the issue in a code review. Although it doesn't directly answer the question, I think it's a very important point to make for those who refuse to use using blocks for disposables.
Jim Schubert
+2  A: 

Not only will a finally block execute following a catch block, try does not even require that any exception be caught for the finally to execute. The following is perfectly legal code:

try 
{
//do stuff
}
finally 
{
   //clean up
}

I actually took out the catch blocks in some code I inherited when the catch block consisted of:

catch(Exception ex)
{
   throw ex;
}

In that case, all that was required was to clean up, so I left it with just a try{} and finally{} block and let exceptions bubble up with their stack trace intact.

Michael Blackburn
@Michael, So if I want something to execute only if no exception is thrown, where would I put that code? Right below the try catch block? Would I have to construct another if statement before or after? I am confused... Thanks!
Scott W
@ScottW: Place the code immediately following the code you expect to throw within the try block.
Steve Guidi
@Michael, Thank you!!!
Scott W
In reference tot keeping the stack trace intact on bubbled up exceptions you can just use <code>throw;</code> sans the <code>ex</code>
gooch
Yeah, I know. The guy ahead of me didn't. That would make sense if you were doing something else in the catch, then wanted to throw. if the ONLY thing you're doing in the catch is throwing it on, well, what's the point of catching it.
Michael Blackburn
@Scott: all code you write only executes when there is no exception. :) Like Steve said, put the code inside the try{} block after the "dangerous" code.One gotcha to avoid is using exception handling as program flow control. For example, trying to parse a user input as an int, and then if you didn't have an exception, pass it to the adder, but if you did have an exception, send it to the string parser.
Michael Blackburn
Generally, you want to code your exceptions to handle events that are not a part of normal program flow. Events that your program has no control over are candidates for exception handling. Examples are user input, status of a network connection, file read errors, etc.
Michael Blackburn