Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try-catch-finally and then again a try catch

I have often come across situations like :-

try{       ...      stmts      ... }  catch(Exception ex) {      ...       stmts      ...  } finally {      connection.close // throws an exception } 

which still needs a try - catch block inside finally.

What is the best practice to overcome this?

like image 756
Ajay Avatar asked Aug 26 '09 16:08

Ajay


People also ask

What happens if catch and finally both return value?

When catch and finally block both return value, method will ultimately return value returned by finally block irrespective of value returned by catch block.

Can we have a return statement in try catch and finally block?

Yes, we can write a return statement of the method in catch and finally block.

When finally block executed in try catch finally?

catch statement is comprised of a try block and either a catch block, a finally block, or both. The code in the try block is executed first, and if it throws an exception, the code in the catch block will be executed. The code in the finally block will always be executed before control flow exits the entire construct.

How do both catch and finally work in an exception program?

Try block contains the code that might throw an exception. Catch block contains the exception handler for exceptions in the try block. The finally block contains the critical code that will execute regardless of whether the exception has occurred or not.


2 Answers

Write a SQLUtils class that contains static closeQuietly methods that catch and log such exceptions, then use as appropriate.

You'll end up with something that reads like this:

public class SQLUtils  {   private static Log log = LogFactory.getLog(SQLUtils.class);    public static void closeQuietly(Connection connection)   {     try     {       if (connection != null)       {         connection.close();       }     }     catch (SQLExcetpion e)     {       log.error("An error occurred closing connection.", e);     }   }    public static void closeQuietly(Statement statement)   {     try     {       if (statement!= null)       {         statement.close();       }     }     catch (SQLExcetpion e)     {       log.error("An error occurred closing statement.", e);     }   }    public static void closeQuietly(ResultSet resultSet)   {     try     {       if (resultSet!= null)       {         resultSet.close();       }     }     catch (SQLExcetpion e)     {       log.error("An error occurred closing result set.", e);     }   } } 

And your client code will be something like:

Connection connection = null; Statement statement = null; ResultSet resultSet = null; try  {   connection = getConnection();   statement = connection.prepareStatement(...);   resultSet = statement.executeQuery();    ... } finally {   SQLUtils.closeQuietly(resultSet);   SQLUtils.closeQuietly(statment);   SQLUtils.closeQuietly(connection); } 

Update: since Java 7, the various JDBC interfaces extend java.lang.AutoCloseable and while the above code answers the original question, if you're writing code directly against the JDBC API, it can now be structured:

try (   Connection connection = getConnection();   PreparedStatement statement = connection.prepareStatement(...);   ResultSet resultSet = statement.executeQuery() ) {   ... } 
like image 158
Nick Holt Avatar answered Oct 06 '22 01:10

Nick Holt


As others have mentioned, a static closeQuietly utility is the way to go. One thing to add - if you are in the world of java.io rather than java.sql then there is a useful interface for exactly this purpose - java.io.Closeable

All the data sources and sinks in java.io implement this interface - all streams, channels, writers and readers. That way you can create a single utility to cope with the same "exception on close()" issue without requiring many overloaded versions.

e.g.

public class IoUtils {    public static closeQuietly (Closeable closeable) {     try {       closeable.close();     } catch (IOException logAndContinue) {       ...     }   }  } 
like image 28
serg10 Avatar answered Oct 05 '22 23:10

serg10