RedHatEMEA / massiveData

A system to store a massive amount of data that is searchable.
0 stars 0 forks source link

Consider policy for wrapping thrown exceptions #2

Open jamesread opened 11 years ago

jamesread commented 11 years ago

@utherp0 So, allow me to explain my thoughts on thrown exceptions, and when it is good to wrap exceptions. Just to be clear, I'll cover the terminology;

_Thrown Exception_

public void testGeneration() throws IOException {
    throw new IOException("This is an exception");
}

_Wrapped Exception_

public void testGeneration() throws GenerationException {
    throw new GenerationException(new IOException("I am the root cause of a generation exception!");
}

Both examples should be used throughout the codebase. In my code, I follow these very simple rule;

_Rule: When to use explicitly thrown exceptions_

Declare thrown exceptions when it is undesirable to catch an exception. Prefer specificity over generalization (ie, if a method throws FileNotFoundException AND SocketException, then prefer to throw both, instead of the higher level IOException (which these both extend from).

By throwing both exceptions here, you can act in two separate ways. eg: log message for FileNotFoundException and system.exit for a SocketException. The calling method cannot handle both cases if you only throw IOException.

_Rule: When to use wrapped exceptions_

Finally, wrapped exceptions should be thrown on interface signatures.

The reason is, the caller of interface methods should have to know nothing about the implementation details (and the exceptions that those implementations might throw).

Also, you cannot prodict all exceptions that an implementation might throw. Lets say you have a PdfGenerator and you want to throw a PdfMalformedException. Because you don't declare this on the interface signature, you'll never be able to catch it. Therefore, you wrap this exception using the constructor GenerationException(Exception cause).

Hope this all makes sense. Let me know what you think.