An oldie but a goodie. The first ExceptionPattern I ever learned.
Once you've decided to use an Exception, the question remains: what to call it ? And the answer is: describe why the Exception is being thrown. There are two main benefits to this:
Good example: java.lang.ClassNotFoundException
Thrown when an application tries to load in a class through its string name using: The forName method in class Class. The findSystemClass method in class ClassLoader. The loadClass method in class ClassLoader.
I have yet to run into this Exception and not know why it was thrown.
Bad Example: java.lang.NoSuchMethodException
Thrown when a particular method cannot be found.
This seems reasonable until you run into it in bizarre places. For example, JavaBeans (and Serialization) require a constructor with no arguments. If you forget to include this constructor, and someone attempts to use your class as a bean, they'll get a NoSuchMethodException. The first time I ran into this, it took me 20 minutes of staring at the stack to figure out what was going on.
-- WilliamGrosso''It would help if they listed the class of the object they were trying to find the method on, and the name of the method...'
The java.lang.NoSuchMethodException, in the case of the Beans, seems like a good candidate for ConvertExceptions. They opted for ThrowDontCatch, but in doing that lost a vital piece of information. It be clearer thrown as a "java.beans.NoDefaultConstructor?". -- RobCrawford
ClassNotFoundException is actually an example of a converted Exception. The original Exception was probably either FileNotFoundException or ConnectionException (depending on whether the class loader tried to load the class from a file or across the net.) And, as any newbie who's tried to install an applet will tell you, knowing which class wasn't found really doesn't tell you enough to figure out *why* Java can't find that class (most likely an error in the applet tag, or it's in the wrong directory).
The problem is that specifically named Exceptions break abstraction - if we implement a class loader that loads classes from a RelationalDatabase, we don't want to modify Class.forName() to throw SQLException. So, we might have to "name the problem" in an attribute of the Exception rather than the Exception type, or by having more than one ExceptionPerContext.
-- BrianSlesinskyThis is why it is important to allow for ChainedExceptions. Some environments (e.g. MS CLI / .Net) support an InnerException property. This allows you to not just "convert" an exception, but to provide the history / context that caused the converted exception. For example, in the ClassNotFoundException example, the exception would have an InnerException property whose value was ConnectionException, which would provide the detailed information on why the connection failed (host unreachable, no tcp listener, protocol error, etc.). -- ArlieDavis