| The failure mode of a component is a function of how it's implemented. When a library couldn't connect to a server or couldn't open a file, you gain nothing by wrapping that exception, unless it's to indicate the semantic nature of the server or what the file is used for - and these things are normally obvious from the stack trace method names. Wrapping exceptions as they bubble up is only helpful if the wrapped exception adds context that aids in diagnosing the issue. Otherwise it's just boilerplate that obfuscates and gives a certain type of developer warm fuzzies. "Exposing implementation" is a non-counterargument - the component failed because its implementation preconditions were violated, you need to address those implementation preconditions to fix the problem! You don't need to import dependencies unless you intend to catch the specific originally thrown exceptions, and that's not normally what happens in the top loop; it normally logs, dumps or transmits the exception message and possibly its stack trace. These operations are normally only rely on the base exception type, so there's no need to catch a more specific exception. Problem languages for this approach, though, are C++ (where the culture makes a single base class for exceptions awkward) and Java (where throws clauses, a deeply misguided feature, may force dependency imports unless you specify 'throws Exception' - or my preference, wrap in RuntimeException). PS: I should add the other fundamental problem with the Java throws clause is that it uses static types to analyze dynamic data flow in a language with polymorphism, which makes it a usability disaster. When the code being invoked is indirectly accessed via polymorphic references, exception flow checking falls apart. There's a reason Google Guava's Function and Predicate interfaces don't throw. But that's enough of my bugbears. |
I don't think this is necessarily true; assuming an XML parsing library that throws exceptions on malformed XML, you are more likely to have simply supplied generally invalid XML than to have hit an implementation-specific exception type.
So, the exception is only implementation-specific in the sense that it was created by an implementation of the class of software you wanted.
But really, in my mind the issue of not wrapping exceptions means all of your client code is now tied to the transitive library, which means the implementation can't be changed without breaking API compat.