2

I am confused about best practice in situation when you need throw multiple exceptions.

Let say that we have exceptions declared as it is shown below.

public class DaoException extends Exception public class ClientNotFoundException extends DaoException public class NotUniqueResultException extends DaoException 

Now we have а method, which can throw ClientNotFoundException and also NotUniqueResultException. What is better to be appled to the throws clause?

getClientByNumber(Long number) throws ClientNotFoundException, NotUniqueResultException 

or

getClientByNumber(Long number) throws DaoException 

?

How do you solve this situation in your code? Do you creatе your own exception hierarchy in your applications?

Is there other possible way how to solve it?

3 Answers 3

4

My personal opinion is that you should be as descriptive as possible for all the possible cases that may occur when the method does some activity, i.e. I would advice to do:

getClientByNumber(Long number) throws ClientNotFoundException, NotUniqueResultException 

The reason for this is that the one that invokes the method will have to deal with both of the cases in which your method throws an exception. Your method may throw different exception under different circumstances, and the way an exception is caught may differ, depending on the type of the exception. For example:

public void myMethod() { try { getClientByNumber(1); } catch (NotUniqueResultException e) { //something that deals with the exception of that specific type. } catch (ClientNotFoundException e) { //something else that deals with the exception of that specific type. } } 
Sign up to request clarification or add additional context in comments.

1 Comment

You can deal with specific types in both cases but in the other case you have to add a superfluous catch( DaoException e) {} block that you know will never be called. Unless something changes in the internals of getClientByNumber()... and hey presto, you've created a bug that is very hard to track down.
3

In my experience it is often best to be specific; thus choosing the throws ClientNotFoundException, NotUniqueResultException solution. That way it is more clear to the user which exceptions can be thrown and what they mean which makes it much easier to handle them.

Creating a hierarchy of Exceptions for your application can be a good idea if the exceptions in question are actually related. However in many cases this is not required; for example the NotUniqueResultException could extend IllegalStateException (as it is, from what I can see, an illegal state).

1 Comment

@Kariton: It also depends on how you want to use the method you are writing. As blalasaadri already said, it is sometimes better to have two different Exceptions thrown, so you can distinguish them and catch them differently. If however the code is only for you and you just want to catch any exception and handle them all in the same manner.. then I think there is nothing wrong to throw just DaoException.. Just be careful and don't end up throwing Exception everywhere because it's so simple :)
0

It's a good idea to declare every type of exception you expect to throw, even those that are runtime exceptions.

One of the reasons for this is Javadoc. Imagine you have something like this.

public void foo( String bar ) throws NullPointerException, IllegalArgumentException { if (bar == null) { throw new NullPointerException( "bar must not be null" ); } if (bar.equals( "123" ) { throw new IllegalArgumentException ( "bar must not have valu 123" ); } ... } 

And in your Javadoc you can document exactly what is thrown when. This is incredibly useful for users of your code, even if they don't want to handle them differently. (Of course you can add the @throws tags to the Javadoc manually, but it's better to be prompted.)

Before Java 7, dealing with many exceptions in one catch was quite complicated, which tempted developers to simplify their throws clauses but there's no justification for that any more.

Try-multi-catch:

try { getClientByNumber(Long number); } catch ( ClientNotFoundException | NotUniqueResultException ex ) { ... } 

This eliminates the need to repeat your catch block (or even worse, catch Exception).

Re-throwing made easy

If for some reason you do want to catch every exception, log it and re-throw it, you can do this:

 public void foo() throws ClientNotFoundException, NotUniqueResultException { try { getClientByNumber(Long number); } catch ( Exception ex ) { ... throw ex; //the compiler knows that at this point `ex` is either an unchecked exception, or one of the two declared checked exceptions, therefore this re-throw is valid } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.