17

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?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Scott W
  • 205
  • 1
  • 2
  • 4

5 Answers5

32

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...

Community
  • 1
  • 1
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
12

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
  • 720
  • 1
  • 5
  • 13
  • @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 Jul 21 '10 at 22:38
  • 2
    @ScottW: Place the code immediately following the code you expect to throw within the try block. – Steve Guidi Jul 21 '10 at 22:41
  • 2
    In reference tot keeping the stack trace intact on bubbled up exceptions you can just use throw; sans the ex – gooch Jul 21 '10 at 22:59
  • 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 Jul 22 '10 at 15:50
  • @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 Jul 22 '10 at 16:02
  • 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 Jul 22 '10 at 16:02
  • 1
    @Michael, *even* if you wanted to do "something else in the catch" before throwing, you *still* shouldn't ever `throw ex`. That annihilates the original stack trace! So even if you *did* want to do something (like logging) before throwing again, you should *still* use the naked `throw;` *or* you should throw a new exception that passes the original one as the inner exception. – Kirk Woll Oct 05 '13 at 01:52
5

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
  • 28,753
  • 28
  • 75
  • 83
1

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
}
Joseph Yaduvanshi
  • 20,241
  • 5
  • 61
  • 69
  • 1
    +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, and 2) 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 Aug 29 '10 at 03:54
  • 1
    @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. – Joseph Yaduvanshi Aug 29 '10 at 04:49
  • 1
    I'd like to hear if there's a valid argument for refusing to use using(). :) – Michael Blackburn Dec 08 '11 at 23:56
  • The argument between me (pro-using) and some of my coworkers (ant-using) is that developers with years of Java experience who then have to work on a .NET project don't understand the using statement. Even Java 7's [equivalent](http://www.infoq.com/news/2010/08/arm-blocks) makes it look like a try block! I agree in a .NET shop of .NET devs, you should use `using()`, but in a mixed shop where maintenance is an issue, I think `try/finally` has it's place. – Joseph Yaduvanshi Dec 09 '11 at 16:52
0

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
  • 410
  • 4
  • 19
  • sorry, my search did not return anything specific to my question that I could see from a glance. – Scott W Jul 21 '10 at 22:17