@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.
@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_
_Wrapped 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_
By throwing both exceptions here, you can act in two separate ways. eg: log message for
FileNotFoundException
andsystem.exit
for aSocketException
. The calling method cannot handle both cases if you only throwIOException
._Rule: When to use wrapped exceptions_
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.