• Post Reply Bookmark Topic Watch Topic
  • New Topic

Exception handling in finally block  RSS feed

 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a method which connects to a database through jdbc, sends some sql to the database and then exists. I used a finally block in the method to ensure that the connection was always closed when the method was exited from ->

public void add() throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
try{
conn = getConnection();

... sql query here ...

}
finally{
if (conn!=null){
conn.close();
}
}
}

There were no problems with this.

Now I want to take the SQLException away from the method, something along the lines of...

public void add() throws DAOException {
Connection conn = null;
PreparedStatement pstmt = null;
try{
conn = getConnection();

... sql query here ...

}
catch(SQLException sqle){
throw new DAOException(sqle.getMessage());
}
finally{
try{
if (conn!=null){
conn.close();
}
}
catch(SQLException sqle){
throw new DAOException(sqle.getMessage());
}
}
}

Which works. But if there's an exception thrown in the first try block then what actually gets thrown from the method? Is it the original exception or the one in the finally block? Is there a better way to do this?

Thanks
 
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
the one from the finally block will be thrown. Which is the best way? It depends on the context of the application, but you generally don't want to throw exceptions from the finally block, as it tends to 0obscure the original issue.

M
 
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I will often turn this inside out:



This removes some duplication and puts all the error-handling in one place.
 
B Stokes
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's what I thought. Should I put a try block around the entire body of the method (including the finally block)?
 
B Stokes
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ernest Friedman-Hill:
I will often turn this inside out:



This removes some duplication and puts all the error-handling in one place.



I assume the finally block will now be executed before the catch block?
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by B Stokes:

I assume the finally block will now be executed before the catch block?


Yep.
 
B Stokes
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your help. My code looks a bit more organised now. And it works too!
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I generally don't: normally speaking, finally blocks shouldn't perform any sustentative processing: this is coding to the exception, and is generally considered to be bad practice. I know that some beginning Java books used to, for example, close db connections in finally blocks, but I've never cared for the practice. generally speaking, if your finally block is part of the processing logic, then you're probably coding to the exception, and should probably reconsider your design.

I will generally only finally blocks for logging or auditing purposes. thus


[ September 30, 2004: Message edited by: Max Habibi ]
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Max Habibi:
I know that some begriming Java books used to, for example, close db connections in finally blocks, but I've never cared for the practice.


What's the alternative? Let's say you want to close a connection whether or not there's an exception while using it, and you want to propagate any exceptions to the caller. Now, how do you accomplish this without duplicating the close() call, except by putting close() into a finally block?
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Of course, it all depends on your needs: but, in the general case, if you want to propagate the closing exception to the caller, then you might have a method like the following, which all of the other methods can use.



However, if you chose not to propagate the closing exception to the caller(maybe the caller can't/shouldn't do anything about the type of DB connectivity issues that might cause a close call to fail), then something like the following suites.

[ September 30, 2004: Message edited by: Max Habibi ]
 
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[B][EFH]:
[/B]
I typically do something like:

Here we rely of getSomething() to never return null. If it can't create Something, it throws an exception instead. And we rely on close() to behave well even if the Something is already closed or otherwise in a questionable state. In my experience both these are usually true, though they're not always explicitly guaranteed.
[ September 30, 2004: Message edited by: Jim Yingst ]
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know Jim: it's been a bit since I've done straight JDBC, but I seem to recall that connection.close throws an exception if you call it on a connection that's already closed? If this is true, then your code, as written, is guaranteed to throw an exception every time.

M
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The API for Connection explicitly states "Calling the method close on a Connection object that is already closed is a no-op." There's a similar guarantee for Statement. Not for ResultSet though. It's certainly possible some JDBC implementations are buggy in this respect, and in that case a more flexible closeConnection() method such as you suggest is certainly an option. I would also (in general) write the doStuffWith(st) method to not call close(), delegating that responsibility to the calling code instead. So close() should get called exactly once anyway. Unless there's another coding error somewhere, or I'm forced to pass the Something reference off to some third-party utility which closes it without telling me...
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!