Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

The classical way to program is with try / catch but when is it appropriate to use try without catch? In Python the following appears legal and can make sense:

try:
  #do work
finally:
  #do something unconditional

But we didn't catch anything. Similarly one could think in Java it would be

try {
    //for example try to get a database connection
}
finally {
  //closeConnection(connection)
}

It looks good and suddenly I don't have to worry about exception types etc. But if this is good practice, when is it good practice? Or reasons why this is not good practice or not legal (I didn't compile the source I'm asking about and it could be a syntax error for Java but I checked that the Python surely compiles.)

A related problem I've run into is that I continue writing the function / method and at the end I must return something and I'm in a place which should not be reached and it must be a return point so even if I handle the exceptions above I'm still returning null or an empty string at some point in the code which should not be reached, often the end of the method / function. I've always managed to restructure to code so that I don't have to return null since that absolutely appears to look like less than good practice.

share|improve this question
2  
In Java, why not put the return statement at the end of the try block? –  kevin cline Jan 23 '12 at 18:52
    
See onjava.com/pub/a/onjava/2003/11/19/exceptions.html for some thoughts on better practice –  Kyle Sep 18 '12 at 7:11
1  
I am sad that try..finally and try..catch both use the try keyword, apart from both starting with try they're 2 totally different constructs. –  Pieter B Sep 18 '12 at 9:34
2  
try/catch is not "the classical way to program." It's the classical C++ way to program, because C++ lacks a proper try/finally construct, which means you have to implement guaranteed reversible state changes using ugly hacks involving RAII. But decent OO languages don't have that problem, because they provide try/finally. It's used for a very different purpose than try/catch. –  Mason Wheeler Apr 25 '13 at 1:21
    
I see it a lot with external connection resources. You want the exception but need to make sure that you don't leave an open connection etc. If you caught it you would just rethrow it to the next layer anyway in some cases. –  Rig Dec 19 '13 at 12:35

7 Answers 7

up vote 90 down vote accepted

It depends on whether you can deal with the exceptions that can be raised at this point or not.

If you can handle the exceptions locally you should, and it is better to handle the error as close to where it is raised as possible.

If you can't handle them locally then just having a try / finally block is perfectly reasonable - assuming there's some code you need to execute regardless of whether the method succeeded or not.

However, you will still need an exception handler somewhere in your code - unless you want your application to crash completely of course. It depends on the architecture of your application exactly where that handler is.

share|improve this answer
2  
"and it is better to handle the error as close to where it is raised as possible." eh, it depends. If you can recover and still complete the mission (so to speak), yes of course. If you cannot, better to let the exception go all the way to the top, where (likely) user intervention will be required to deal with what happened. –  Will May 2 '12 at 12:59
4  
@will - that's why I used the phrase "as possible". –  ChrisF May 2 '12 at 13:00
3  
Good answer, but I would add an example: Opening a stream and passing that stream to an inner method to be loaded is an excellent example of when you'd need try { } finally { }, taking advantage of finally clause to ensure stream is ultimately closed regardless of success/failure. –  Neil Oct 24 '12 at 9:35

The finally block is used for code that must always run, whether an error condition (exception) occurred or not.

The code in the finally block is run after the try block completes and, if a caught exception occurred, after the corresponding catch block completes. It is always run, even if an uncaught exception occurred in the try or catch block.

The finally block is typically used for closing files, network connections, etc. that were opened in the try block. The reason is that the file or network connection must be closed, whether the operation using that file or network connection succeeded or whether it failed.

Care should be taken in the finally block to ensure that it does not itself throw an exception. For example, be doubly sure to check all variables for null, etc.

share|improve this answer
4  
+1: It's idiomatic for "must be cleaned up". Most uses of try-finally can be replaced with a with statement. –  S.Lott Jan 23 '12 at 18:07
6  
Various languages have extremely useful language-specific enhancements to the try/finally construct. C# has using, Python has with, etc. –  yfeldblum Jan 23 '12 at 18:16
2  
@yfeldblum - there is a subtle diff between using and try-finally, as the Dispose method won't be called by the using block if an exception happens in the IDisposable object's constructor. try-finally allows you to execute code even if the object's constructor throws an exception. –  Scott Whitlock Feb 15 '12 at 16:27
3  
@ScottWhitlock: That's a good thing? What are you trying to do, call a method on an unconstructed object? That's a billion kinds of bad. –  DeadMG Feb 15 '12 at 16:55
    
@DeadMG: See also stackoverflow.com/q/14830534/18192 –  Brian Apr 25 '13 at 3:21

An example where try... finally without a catch clause is appropriate (and even more, idiomatic) in Java is usage of Lock in concurrent utilities locks package.

  • Here's how it is explained and justified in API documentation (bold font in quote is mine):

    ...The absence of block-structured locking removes the automatic release of locks that occurs with synchronized methods and statements. In most cases, the following idiom should be used:

     Lock l = ...;
     l.lock();
     try {
         // access the resource protected by this lock
     } finally {
         l.unlock();
     }
    

    When locking and unlocking occur in different scopes, care must be taken to ensure that all code that is executed while the lock is held is protected by try-finally or try-catch to ensure that the lock is released when necessary.

share|improve this answer

At a basic level catch and finally solve two related but different problems:

  • catch is used to handle a problem that was reported by code you called
  • finally is used to clean up data/resources that the current code created/modified, no matter if a problem occurred or not

So both are related somehow to problems (exceptions), but that's pretty much all they have in common.

An important difference is that the finally block must be in the same method where the resources got created (to avoid resource leaks) and can't be put on a different level in the call stack.

The catch however is a different matter: the correct place for it depends on where you can actually handle the exception. There's no use in catching an exception at a place where you can do nothing about it, therefore it's sometimes better to simply let it fall through.

share|improve this answer
    
Nitpick: "... the finally block must be in the same method where the resources got created ... ". It is certainly a good idea to do it that way, because it is easier to see there is no resource leak. However, it is not a necessary precondition; i.e. you don't have to do it that way. You can release the resource in the finally of a (statically or dynamically) enclosing try statement ... and still be 100% leak-proof. –  Stephen C Apr 25 '13 at 4:32

@yfeldblum has the correct answer: try-finally without a catch statement should usually be replaced with an appropriate language construct.

In C++, it's using RAII and constructors/destructors; in Python it's a with statement; and in C#, it's a using statement.

These are nearly always more elegant because the initialization and finalization code are in one place (the abstracted object) rather than in two places.

share|improve this answer
1  
And in Java it's ARM blocks –  MarkJ Feb 15 '12 at 15:33
    
Supposing you have a badly designed object (For instance, one which doesn't appropriately implement IDisposable in C#) that isn't always a viable option. –  mootinator Feb 15 '12 at 19:00
    
@mootinator: can't you inherit from the badly designed object and fix it? –  Neil G Feb 15 '12 at 22:40
1  
Or encapsulation? Bah. I mean yes, of course. –  mootinator Feb 16 '12 at 15:26

In many languages a finally statement also runs after the return statement. This means you can do something like:

try {
  // Do processing
  return result;
} finally {
  // Release resources
}

Which releases the resources regardless of how the method was ended with an exception or a regular return statement.

Whether this is good or bad is up for debate, but try {} finally {} is not always limited to exception handling.

share|improve this answer

Catching errors/exception and handling them in a neat manner is highly recommended even if not mandatory.

The reason I say this is because I believe every developer should know and tackle the behavior of his/her application otherwise he hasn't completed his job in a duly manner. There is no situation for which a try-finally block supersedes the try-catch-finally block.

I will give you a simple example: Assume that you have written the code for uploading files on the server without catching exceptions. Now, if for some reason the upload fails, the client will never know what went wrong. But, if you have caught the exception, you can display a neat error message explaining what went wrong and how can the user remedy it.

Golden rule: Always catch exception, because guessing takes time

share|improve this answer
21  
-1: In Java, a finally clause may be needed to release resources (e.g. close a file or release a DB connection). That is independent of the ability to handle an exception. –  kevin cline Jan 23 '12 at 18:47
60  
@Pankaj: your answer suggests that a catch clause should always be present whenever there is a try. More experienced contributors, including me, believe this is poor advice. Your reasoning is flawed. The method containing the try is not the only possible place the exception can be caught. It is often simplest and best to allow catch and report exceptions from the top-most level, rather than duplicating catch clauses throughout the code. –  kevin cline Jan 23 '12 at 19:25
13  
@NickRosencrantz, please consider unmarking this answer as the solution. A try/finally clause is used to ensure that resources are not leaked in languages that do not feature RAII (among other techniques). This answer shows a gaping lack of knowledge, and I urge you to consider selecting a different answer. –  Stargazer712 Feb 16 '12 at 3:52
6  
-35 and accepted.. surely that's a record of some kind? Anyway, "always catch exceptions" is not a good rule of thumb. Yes, you want to catch exceptions that you can recover from.. however, it's better for your application to die a loud in-your-face death than run with corrupt state and produce unpredictable, possibly more business-critical results further into its lifetime. –  Simon Whitehead Sep 18 '12 at 14:01
2  
@SimonWhitehead it was. Now its -63 and unaccepted. ChrisF's answer was accepted on September 15th. –  MichaelT Oct 2 '13 at 15:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.