views:

322

answers:

10

If we are to catch specific forms of IOException, or any other kind as a matter of fact, and we only try and catch a couple (and define definitive outputs for them) say

FileNotFoundException
ZipException

should we always trail it off and cover all bases with a

catch(IOException e){
    e.printStackTrace();
}

and then possibly go even further and catch Exception e, or is this a complete waste of time?

+2  A: 

The higher the exception hierarchy you're catching, and not handling them properly, or rethrowing, the more problems you will put under the carpet. You can have silent bugs that are hard to track.

So catch only appropriate Exceptions, and let the others pass. In the top level, you can have a catch all if you don't want to crash your program, but at least log it. Still this is questionable approach, because your application could be in inconsistent state, and you can do damage to your data.

But to answer directly to your question, IOException might be at the appropriate level. It could be enough to know for you that whatever the problem was, it related to IO, and you can act according to it. It's hard to say without more information.

egaga
Re: inconsistent state, I believe finally blocks always execute in Java as the exception flies up the stack, regardless of whether the exception is caught or not. So even if you are careful not to catch "fatal" exceptions to avoid executing when in an inconsistent state, you have no way to stop your finally blocks executing. So IMO this is a moot point in the JRE, unless you avoid the use of finally blocks, which seems like a terrible thing to have to give up. The .NET CLR is different - you have the option to abort BEFORE finally blocks run if there is an unhandled exception.
Daniel Earwicker
+8  A: 

Generally, you only want to catch and handle exceptions you can do something with at a low level. Then at a higher level, catch any unhandled exceptions system wide, so you can record errors that occurred.

Shane Fulmer
+1  A: 

Like a good consultant, I say "it depends."

In general in Java you have a clear idea of what all the possible exceptions at a particular point in the code might be. It's not uncommon to see someone use

} catch (Exception e){
   // log or stack trace
}

... in more or less throwaway code. In general, though, you shouldn't catch an exception you don't know how to handle usefully. (Never, never ever, do catch (Exception x) ;, ie, just throw away the exception. Never.)

The controlling thing is to ask "what can I do with this?" Often, a file not ound exception can be handled by asking a user where his file has gone. A zip file exception is harder to handle. Thus, you might want to have separate behaviors.

On the other hand, if it's a command line program, you might want nothing more than an error message in either case.

One other bit of advice; don't output a stack trace in "cutomer facing" code -- code that a non-programmer might see. Nonprogrammers tend to look at the compleities of a stack trace and panic. It's better to translate the exception to a message like "File 'filename' not found." and, if you really want a stack trace, ose logging to send it to debug level output.

Charlie Martin
+4  A: 

Generally, you should only catch exceptions you are going to handle explicitly.

You should not catch Exception, IOException, et. al., unless you are an appropriately high level where you are doing your last ditch catch to report a general error to the user.

Adam Luter
A: 

You should not catch these at every possible location where an IOException can happen but further up in the call tree where you are prepared to handle the remaining IOExceptions and the general Exceptions.

We use the rule of thumb, that you catch specific exceptions at the place where you can handle the error and pass the remaining ones up to the caller.

Kosi2801
+1  A: 

Blankly catching any kind of exception is not a good idea. Yes, as a parent exception, it seems to provide a layer of "protection", but this is bad for a few reasons:

IOExceptions are checked. If there's nowhere in the code that's throwing it adding an unneeded catch just obscures things, and will likely confuse anyone looking at the code later.

More importantly, you don't catch exceptions to just make them go away. If they did, you could just wrap all your methods in (catch(Exception e){..}) and be done with it. Your exception catching code should be the place where you decide what to do if those errors happen, e.g.

catch(FileNotFoundException e)
{
 log.error("where's the file?");return null;
}
catch(ZipException e)
{
 log.error("corrupt");return null;
}

The point is to make the method well behaved under all possible conditions. The caller then deals with, for example, either file content or no content, without worrying about how the content got there.

Steve B.
Not to be a prick about it; but when I see this I think this will cause an NPE somewhere else.
sal
+3  A: 

If in doubt, always catch the more specific exception!

James L
A: 

I'll echo "catch the most specific exception you can".

I routinely catch IOException and display some sort of "error reading file" message, then allow the user to select another file or whatever is appropriate. If the file is really bad, there's probably not much the user can do about it, but at least you can let them know the file is bad.

If you get a FileNotFoundException the real problem is almost surely that the user seleected the wrong file name or a hard-coded file name is no longer valid. I routinely display messages for that.

I almost never catch "Exception". What are you going to do about it? There's pretty much nothing you can do to recover from "something went wrong but no further details are available". In some contexts I suppose you could at least display an error message rather than just dying, but that's about it.

Jay
A: 

It depends if a more specific Exception will aid in the trouble shooting. Sometimes, like with JMX, its good to just catch the parent exception to avoid a long list of possible child exception. At least Java 7 will allow us to have more that one exception per catch. That will clean up the code quite a bit.

Javamann
+1  A: 

I think it is a matter of personal preference. Personally, this seems not to be a good choice. I prefer to have code that makes sense to me with the try-catch stuff. This means being as specific as possible. I would say:

try{
    //Code Here
}
catch(FileNotFoundException e){
    //Code Here
}
Nathan Lawrence