• Post Reply Bookmark Topic Watch Topic
  • New Topic

About good exception handling practices?  RSS feed

 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Ranchers

I started with Java like a year and a half ago and I started to develop my first real-world applications like 6 months ago. Hence, as you can imagine, I need to gain experience...

I still get a bit confused when it comes to the right practices for exception handling. I have read a lot about the subject, but obviously not enough to take me out of doubts sometimes.

What about this case:

I am writing an small class that execute batch SQL scripts.



What would you guys do in lines 14 and 21?

There is no point here, I can't think of anything to recover from the exception, it does not make much of a sense to propagate the exception either, I frankly don�t see it would be of a great help if I log it. And supposedly, just ignoring a caught exception is not exactly a good practice.
[ May 03, 2006: Message edited by: Edwin Dalorzo ]
 
Paul Clapham
Sheriff
Posts: 22701
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's unlikely that those exceptions will ever occur. But if they do, who should be notified? Not the user, who was just trying to change the time of their appointment or something. What do they know? It's the people in the back room -- you or the people who keep the systems running -- who want to know.

Probably if those exceptions do occur, it's because something really weird is happening. And it's likely that the operations people already know, because there are more visible errors occurring. But just in case there's a database bug that only fails to close connections in some unlikely circumstance, maybe you ought to log it.

I use log4j and I have it configured so error-level logging entries are e-mailed to somebody. This might be a place to log an error, even if it may almost never happen.

Although I have to say, mostly I leave those catch-blocks empty. Wouldn't be hard to throw a single line of logging code in there, but laziness conquers all.
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Paul.

I agree with the logging point of view the way you presented it. Altough I have to admit that I was using empty catch blocks too for these cases.

I have also seen an interesting approach used by the ThreadGroup class to handle uncaught exceptions, which is registering a class to handle the exceptions or at least a class that is notified that something happened.

I have been experimenting with a exception handler like this in a small class library I am building.

What do you think of this approach?
[ May 03, 2006: Message edited by: Edwin Dalorzo ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm a big advocate of carefully logging any exception which you don't completely understand the cause of at the time you catch it. Which is to say, almost all exceptions - though there are a few situations where you know the cause and you don't care about the stack trace. (InterruptedException is a common example.)

But going back to the original code here, there are two significant problems. The really big one is: what about the very first catch block for SQLException e, on line 9? Something went wrong in the preceding SQL code... and then you do a rollback, and you close the connection, and probably nothing will go wrong there, and if it does there's not much you can do about it anyway. OK. But what about the original exception? Something went wrong, And after this code runs, THERE IS NO INDICATION ANYWHERE THAT A PROBLEM HAS OCCURRED. No error message. No log file. If someone eventually looks at the database, they may notice that some expected data is missing. Or not. But it's going to take some work for someone to figure out what went wrong here. With luck, that person will be you. Because if it's someone else, and they spend a long time tracking this down before they find this one bit of code here that has successfully hidden the evidence of the error, and they find out you are the author...

Well, that's the sort of thing that motivates hardworking programmers to lock their co-workers in empty rooms and force them to listen for hours to Barry Manilow recordings. Or other similar forms of torture.

Seriously, exceptions contain valuable, useful information. Typically including actual error messages in addition to the stack trace itself. This is really good stuff to have a record of when things go wrong. You never, ever want to just lose an exception just because you weren't sure what to do with it. That just makes it much harder to debug problems later. Using a logging framework is a good idea - but even if you don't have one set up yet, at the very least you can call e.printStackTrace(). That usually does a pretty good job of dumping all the info you need someplace it will probably be found. Much better than doing nothing.

In the above code, you weren't doing nothing, but you let confusion over what to do about the second and third catch blocks (lines 12 and 19) prevent you from logging the most important exception, the one on line 9. That's the one that would tell you what SQL error actually started whatever problem you may be having.

I mentioned two problems. The other one is, what if there's an error on line 2? You'll go to the catch block, and then the finally block... but the connection is null. So lines 11 and then 18 will both throw NullPointerException. Oops. There are two was to avoid this. One is to put "if (conn == null)" checks before the rollback() and the close(). The other, which I prefer, is to place try/catch/finally blocks carefully such that the rollback and close do not occur at all unless getConnection() succeeds:

Of course e.printStackTrace() can be replaced with proper logging - as long as you do something.
[ May 04, 2006: Message edited by: Jim Yingst ]
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Excellent, nifty advises, Jim. Certainly I am going to follow them all.

Thanks for taking your time to write such a complete answer.

 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
At first blush, I like your idea of an exception handler. You could plug in different implementations for development and production or tune the production one to different levels of logging in a running system. It might reduce duplication throughout your system.

Edwin, tell us more about what your handler does!
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Stan. Thanks for participating.

Well, I was building a very small data access layer based on transactions scripts.

I am using Jakarta Commons DBUtils and I have an implementation for an interface I call SQLTask which have an execute method that I implemented somewhat like this:



Then I have an interface for the exception handler, somewhat like this:




And, I use it somewhat like this:



I am using the exception handler in line 06. Of course, a better idea would be sharing the execption handler with all SQLTasks, however as this is a library, I was just running some tests.

I am not sure this approach is a good idea. Altough, until now, seems to work fine.

What do you think, Stan? Any ideas about how to do it better?

Thanks in advance to you all for your participation!
[ May 04, 2006: Message edited by: Edwin Dalorzo ]
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was reading some Spring code before I saw this and realized they did a neat job of moving little bits of logic into their own classes so you could easily plug together different combinations. I find it appealing to delegate as much housekeeping as possible to little classes and keep the main classes focused on their jobs. I'll have to ponder the exception handler a little longer.

I also just read a rant about "handler", "helper" and "manager" objects. Some folks don't seem to like them at all. Spoilsports.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!