2

What is the best practice in using Try Catch Finally block? Do you prefer to use only try finally block and not try catch block? I always thought that try catch finally is the best practice to use. However, in part of the code I am working with I have seen code like this:

try{ doSomething(); } finally{ doSomethingElse(); }

Since they don't catch the exception it was really hard for me to debug the code. It wasn't a really good practice to me not using catch and only finally, but I might be wrong.

To best of my understanding, this is not really a good practice. Basically, we are not making use of what try catch was intended to be used for. I have found similar questions as well.

My questions is: "Do you agree with me on the following hypothesis: The best practice is to use try catch finally together and not try finally." If you do not agree, would you please provide me with an example of when to use try finally instead of try catch finally and why you think try finally is better than try catch?

Community
  • 1
  • 1
sheidaei
  • 9,842
  • 20
  • 63
  • 86
  • @Perception I have mentioned that in the original question. It is not duplicate to me, since he didn't ask when to use try finally block directly. I might be wrong. – sheidaei Apr 03 '13 at 19:03
  • thats pretty much what the other question author means when he asks 'is using try/finally without a catch an anti-pattern'. Anti-pattern in this context being a practice that should not be followed (aka not best). Your questions are essential duplicates. – Perception Apr 03 '13 at 19:07

5 Answers5

6

I disagree, if you cannot do anything about an exception being thrown, but something further up your caller hierarchy can, then use the finally to clean up your resources and let the caller deal with cleaning up after the exception is thrown.

Chris Cooper
  • 4,982
  • 1
  • 17
  • 27
  • in this case, you would have a catch that throws a new exception to the calling function, no? – 75inchpianist Apr 03 '13 at 18:53
  • 1
    This is absolutely right. There are times that you may not be able to handle an exception, or do not want to do so, but you do want to make sure an error doesn't cause your resources to be left open, hindering performance on subsequent runs. In this case, try-finally is excellent. – ehdv Apr 03 '13 at 18:53
  • @75inchpianist Why bother? As I said, there is nothing you can do to handle the situation, so let the exception percolate until it can be dealt with, but the does not excuse the code closer to the exception from dealing with cleaning up resources. In my code where this happens, I will typically document what I expect to be thrown and when to reduce the confusion. – Chris Cooper Apr 03 '13 at 19:01
  • @75inchpianist, no. If an exception is thrown, it will be thrown up the stack until something handles it. It doesn't "dissapear" in a try{}finally{} because nothing caught it – user606723 Apr 03 '13 at 19:01
  • @ChrisCooper so let's say we use try finally block in our code, and an exception happens, so first the code in finally block gets executed and then the catch block (if exists) in calling classes? – sheidaei Apr 03 '13 at 19:06
  • 2
    @sheidaei Yes, that's exactly how it works. Unless your finally code throws an exception, if that happens, then the original exception gets suppressed, and in my opinion finally blocks should never be allowed to throw an exception (but they should log them though). – Chris Cooper Apr 03 '13 at 19:08
2

I do not agree.

try{}finally{} should be used in cases where you cannot handle the exception, but are required to clean up resources.

A try{}finally{} block will not cause the exception to "disappear" as you seem to think it will. It will be thrown up the stack and be handled somewhere else. If you are unable to see the exception in your current application it's because it's being thrown away elsewhere.

try {
    connection = createConnection();
}
finally {
    closeConnection(connection) //Free database connection.
}

In this case, you may not have any ability to handle an SQL exception, but you still want to free the database connection.

user606723
  • 4,918
  • 2
  • 27
  • 34
  • don't you think that it would be better to have a catch block to catch exception, to at least log the situation and then throw it again? – sheidaei Apr 03 '13 at 19:11
  • @sheidaei, no. Doing this is an anti-pattern and leads logs that have each exception logged a dozen times. The exception will get thrown up the chain and logged eventually. Possibly by the VM. – user606723 Apr 03 '13 at 19:23
1

The purpose of the finally construct is to provide code that will always execute, even if an exception is thrown.

The try / finally (no catch) allows you to write code that is guaranteed to execute even if a runtime exception is thrown by the code inside the try block.

This is good in situations where you are using code that might throw runtime exceptions but does not throw checked exceptions. An example of this is Spring DAO support; which wraps IOExceptions in runtime exceptions.

DwB
  • 37,124
  • 11
  • 56
  • 82
  • This is a good point. However, I argue that since you are having a try finally block why not make it a try catch finally block. In catch block, catch the most common exception, log it and then throw it if you don't want to deal with it. This way, if you are having a problem, you can easily check where you go wrong. Am I missing something? – sheidaei Apr 03 '13 at 19:17
  • It is possible that I will not know what RuntimeExceptions are thrown by 3rd party code. The try/finally allows me to close my resources and avoid the use of catch(Exception blammy) blocks. – DwB Apr 03 '13 at 19:19
1

Generally try-finally is used to assure that some piece of code gets executed irrespective if the exception occurs or not. Catch block is generally missing because code in try block does not throw any checked exception which can be caught.

Eg:

try  {

        if(str.length() > 0) { // If str is null, it can throw NullPointer and hence code below it wont execute
            // some code
        }

    }finally {
        // Will be performed even if any unchecked exception is thrown
        // Must contain code which has to be performed at any cost like releasing occupied memory
    }
Ankur Shanbhag
  • 7,746
  • 2
  • 28
  • 38
  • This is a good point. However, I argue that since you are having a try finally block why not make it a try catch finally block. In catch block, catch the most common exception, log it and then throw it if you don't want to deal with it. This way, if you are having a problem, you can easily check where you go wrong. Am I missing something? – sheidaei Apr 03 '13 at 19:16
1

There are three possibilities, try+catch, try+finally, or try+catch+finally. They all have their uses.

Use the catch with try when there's something you can usefully do to handle the exception, such as report the fact that the exception has occurred.

The code inside the finally block always runs, independent of whether an exception occurs or not, so use finally with try when there's cleaning up to do that's always got to happen. An example would be closing a file if it's been successfully opened.

Stochastically
  • 7,616
  • 5
  • 30
  • 58
  • so isn't it a better practice to catch the exception, do something about it (log it for example at least) and then throw exception if I can not do anything with the exception? – sheidaei Apr 03 '13 at 19:08
  • You certainly could do that, but for me it's not best practice. For one thing, it means that the same exception might get logged many times, once in each catch block as the call stack unwinds. I think it makes more sense to have your exception logging at the highest level and use a StackTrace method to determine and log where the exception occurred. This also has the advantage of keeping the code smaller if there's nothing you can do to handle the exception. – Stochastically Apr 03 '13 at 19:33
  • @Stochastically: While duplicate log entries should generally be suppressed when logs are displayed, they can sometimes be useful when trying to track down cases where an exception seems to "disappear". I dislike catch-and-rethrow on general principle (there should be a "fault" block which would have no pretense of handling an exception) but logging an exception's progress up the call stack seems like a good idea. – supercat Oct 24 '13 at 19:00