3

I have written an interface and an implementation to it and I can't really decide on the best way to handle the following problem. To make it short, let's say this is the interface:

public interface Node {
    String getNodeName();
    Node getChildByName(String name);
    void addChild(Node node);
    void removeChild(Node node);
}

Now if I wanted to handle exceptions, is it a good idea to make the exception as generic as possible or should I add rather specific ones?

Let's say the method addChild, should it throw a generic NodeException that could potentially be used in any other method so that the implementing class can extend it on demand, or is it okay to go with a NodeAdditionException that only this methods should throw? The advantage of a generic exception would be that I don't need to wrap exceptions if I use one of the methods internally and an exception is throws, I can just let it go up the stack until someone catches it. It will usually go up to the caller of my implementation and he needs to deal with it then. The caller can catch the generic exception to handle all the exceptions with just one routine or catch any of the child classes. This is at the same time a huge disadvantage, as the caller potentially could catch many different child exceptions that don't even need to be used in the current implementation. That is kind of a deal breaker. A way to solve this is to create a set of fixed exceptions for the implementation to be used which also isn't what I would want to do.

The other way would be the specific exception but this also comes at a price. You would have a fixed set of exception that can be thrown and that's it, an advantage, but if you use any method internally you need to catch the exception, wrap it up in a new one and throw it again. If I got it right, this is quite resource heavy and it's a lot of boiler plate code to write, too. In the end I would take this as the cleaner method to handle exception.

Is there any other way to handle exceptions but this that I just can't think off right now, have I overlooked an important detail on these two or do I need to chose the lesser of these two evils? Any help appreciated.

0

3 Answers 3

3

Have an inheritance structure in your exceptions; for example, NodeAddException extends NodeException. That way, the catcher of an exception can be as specific or as general as it needs to be.

Sign up to request clarification or add additional context in comments.

1 Comment

In the end I stayed with this. I took NodeException as the parent exception that will be thrown by all the methods but internally I extend them, i.e. as NodeNotFoundException. The advantage of this is that I can potentially manage certain exceptions in my implementation and in the case that I cannot handle it, I'll just throw it up to the caller who then needs to take care of it.
2

You could just use unchecked exceptions (i.e. - have your exceptions extend RuntimeException). That way you don't have to declare anything thrown, and implementations can throw anything they like (again, as long as they extend RuntimeException).

6 Comments

Unchecked exceptions should be used only if an exception really indicates there's a bug somewhere else in your program. They shouldn't be used if, for instance, the exception was due to bogus user input. On the other hand, it's hard to imagine why an addChild method like this would ever throw an exception unless there were a bug. But don't use unchecked exceptions just to avoid having to write throws clauses.
@ajb That was the thinking a while ago. Most of the industry has moved toward unchecked exceptions, not because writing throws clause is a pain, but because checked exceptions often have to be caught, re-typed, and re-thrown as they bubble through the layers of the application. That's why modern frameworks (like Spring) deliberately catch checked exceptions from the Data Access layer and re-type them as unchecked.
Interesting article here on the topic... javacodegeeks.com/2012/03/…
It's worth noting that "checked vs unchecked exceptions" is the new "tabs vs spaces".
@Viciouss Glad you got something that worked for you. Keep in mind, though, that using an inheritance structure for exceptions does not mean that those exceptions have to be checked exceptions. You could simply build your exception hierarchy starting with java.lang.RuntimeException as the root class, instead of java.lang.Exception. This allows you to fine-tune your catch clauses to catch only what you want while letting the others bubble up the stack. The only difference is that you aren't forcing the caller to explicitly catch anything, which can save you some syntactic clutter.
|
-1

Unless you're giving NodeException special functionality that does not exist in Exception and does exist in NodeAdditionException/NodeRemoveException/etc., you shouldn't be making a super-exception for your Nodes. The client caller will likely use catch(Exception ex){...} if they want a catch-all, anyway. If there isn't any extra functionality there, there is no need for NodeException.

If you do have shared functionality between various NodeException subclasses which doesn't exist in Exception, that's a different story, and you should definitely use a superclass.

1 Comment

You usually do not want to catch Exception itself or even worse, Throwable! Don't do it if you don't have a damn good reason to. This will in 99,99% of all cases lead to behavior that you do not want as you are catching everything, all exceptions, checked or unchecked, no matter what. You can hide all kinds of failures in your software with this without even noticing it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.