tags:

views:

49

answers:

3

I've read a few other posts like this one about avoiding repetition in Java catch blocks. Apparently, what I really want is "multi-catch", but seeing as Java 7 isn't here yet, is there a good pattern to let me add state to my exceptions, then re-throw them, without catching the kitchen sink?

Specifically, I have some code that makes library calls, which can throw exceptions, but don't provide nearly enough context for successful debuging. I find myself having a problem, then going in, wrapping the library call in a try/catch, catching the specific exception, then adding extra state information in the catch block and re-throwing the caught exception. I then re-iterate through that loop over and over, each time finding a new error condition to log. I wind up with

try {
  make_library_call();
}
catch (SomeException e){
  throw new SomeException ("Needed local state information is " + importantInfo, e);
}
catch (SomeOtherException e){
  throw new SomeOtherException ("Needed local state information is " + importantInfo, e);
}
catch (YetAnotherException e){
  throw new YetAnotherException ("Needed local state information is " + importantInfo, e);
}

etc etc. I think what I'd really like to see is more along the lines of

try {
  make_lib_call();
}
catch(Exception e){
  e.AddSomeInformationSomehow("Needed Info" + importantInfo);
  throw e;
}

assuming that in that case e would keep its actual runtime type when re-thrown -- in this case, even catching unchecked would probably be OK since I'd be re-throwing them, and they'd benefit from carrying the extra state info as well. I guess an alternate might be something like

try{
  make_lib_call();
}
finally {
  if (/*an exception happened*/)
    logger.debug("Some state info: " + importantInfo);
}

but I don't know how to write the conditional. Is that crazy / wrong?

+2  A: 

For the alternative:

boolean isOk = false;
try{
  make_lib_call();
  isOk = true;
}
finally {
  if (!isOk)
    logger.debug("Some state info: " + importantInfo);
}
ob1
You're *correct*, I just wish this wasn't the answer -- I thought of this, but it's a little ham-fisted. It feels like something I'd do in C :(
Coderer
A: 

I'd do something like:

try {
  make_lib_call();
}
catch(Exception e){
  throw new MyException(e, "Needed Info" + importantInfo);
}
Nathan Hughes
This has the same problem as Mark Peters commented on above -- you lose the granularity of having your method throw various exceptions depending on what actually went wrong. There's no real difference between your code and just `throw new Exception(etc etc)`, because only one exception type ever makes it up to the calling method.
Coderer
+2  A: 

You're probably expecting this, but no, there isn't a good (and by good I mean clean) way to do this. You're probably expecting it because you subconsciously knew that if there was a good pattern for doing this, it probably wouldn't have been worth adding to Java 7.

It's actually the final rethrow feature that you'd find really handy in this case.

Mark Peters