views:

211

answers:

5

What is the general rule of thumb when deciding whether to add a throws clause to a method or using a try-catch?

From what I've read myself, the throws should be used when the caller has broken their end of the contract (passed object) and the try-catch should be used when an exception takes place during an operation that is being carried out inside the method. Is this correct? If so, what should be done on the callers side?

P.S: Searched through Google and SO but would like a clear answer on this one.

+4  A: 

In general, a method should throw an exception to its caller when it can't handle the associated problem locally. E.g. if the method is supposed to read from a file with the given path, IOExceptions can't be handled locally in a sensible way. Same applies for invalid input, adding that my personal choice would be to throw an unchecked exception like IllegalArgumentException in this case.

And it should catch an exception from a called method it if

  • it is something that can be handled locally (e.g. trying to convert an input string to a number, and if the conversion fails, it is entirely valid to return a default value instead),
  • or it should not be thrown (e.g. if the exception is coming from an implementation-specific lower layer, whose implementation details should not be visible to the caller - for example I don't want to show that my DAO uses Hibernate for persisting my entities, so I catch all HibernateExceptions locally and convert them into my own exception types).
Péter Török
Ok. To reformulate, an exception would be thrown when an immediate solution isn't possible and some interaction is needed "above" to decide what to do. Also, an exception wouldn't be rethrown if it is only has a "meaning" between a group of classes and a more generalized exception should be thrown in it's place to inform the caller that it's attention is needed. Does this sound more or less right?
James P.
@James, more or less :-) If by "interaction" you mean asking user intervention, it is not always needed. Also, instead of "more generalized" I would prefer "different". A user-defined ConnectionException is no more general than HibernateException.
Péter Török
+8  A: 
  • catch an exception only if you can handle it in a meaningful way
  • declaring throwing the exception up if it is to be handled by the consumer of the current method
  • throw exceptions if they are caused by the input parameters (but these are more often unchecked)
Bozho
Right, the third rule is very clear. About handling an exception in a meaningful way, is this in the higher layers of a program? Does this mean that APIs tend to generally throw Exceptions? Also, in what cases should a method rethrow exceptions coming from submethods (coming from private utility methods for example)?
James P.
well, it vastly depends. APIs throw exceptions, yes. But then comes the choice of checked vs unchecked.
Bozho
Why rethrow the exception? Just don't catch it and pass it up the call stack.
Steve Kuo
@Steve Kuo - that's what I meant. I'l make it clearer.
Bozho
+2  A: 

My personnal rule of thumb for that is simple :

  • Can I handle it in a meaningful way (added from comment)? So put code in try/catch. By handle it, I mean be able to inform the user/recover from error or, in a broader sense, be able to understand how this exception affects the execution of my code.
  • Elsewhere, throw it away

Note : this replys is now a community wiki, feel free to add more info in.

Riduidel
Can I handle it *in a meaningful way*.
Nivas
What are your criteria for deciding if you can handle an exception locally? Is this on the level where you can actually take care of the exception and display a message for example?
James P.
Throwing it away is a bad idea. Better is to pass it up the call stack.
Steve Kuo
+1  A: 

If the method where the exception got raised has a sufficent amount of information to deal with it then it should catch, generate useful information about what happened and what data was being processed.

Alberto Zaccagni
+1  A: 

Here's the way I use it:

Throws:

  • You just want the code to stop when an error occurs.
  • Good with methods that are prone to errors if certain prerequisites are not met.

Try-Catch:

  • When you want to have the program behave differently with different errors.
  • Great if you want to provide meaningful errors to end users.

I know a lot of people who always use Throws because it's cleaner, but there's just not nearly as much control.

Justian Meyer
You should almost NEVER use exception handling for program control. It is a terrible practice.
CheesePls
There's also Try-catch-rethrow, or try-catch-wrap-throw--i.e., just because you can handle the exception in a meaningful way doesn't mean you're done. The method should do what its name indicates it will do, or should throw an exception: http://abstractions-r-us.blogspot.com/2010/06/do-your-work-or-throw-exception-example.html. (shameless plug for my blog)
apollodude217