Why do so many people assume that this fact (that java.lang.Exception is not final) is an oversight made by SUN during the specification of the Java language?
Many people have an aversion to wrapping exceptions that can only be described as religious in its fervor. These people seem to think that it’s not possible to provide any meaningful information in the wrapping exception. Apparently, the only way to solve problems which result in an exception being thrown is to get the stack trace and find the line of source code…and debug from there.
What does this attitude imply? It means that users cannot possibly solve even the simplest problems (“plug in the damned network cable, moron!”) by themselves. Therefore, any problem, however menial or trivial, must be solved by a programmer who knows how to read stack traces. I qualify this, because it’s shocking how many programmers can’t read a stack trace.
If you ever intend to package and ship an application to a user, this is simply not good enough. That user has to be the first line of defense when it comes to troubleshooting, and stack traces (however short they are, due to misguided frugality in exception-wrapping practices) will not help. But this attitude has wider-ranging implications than mere end-user support.
If you have an application that you’ve designed from the ground up, and you have full control and knowledge about each piece in the classpath, I can see it being okay to avoid wrapping exceptions as they propagate upwards. Not great, but okay. You don’t integrate with any other APIs, and you are ultimately responsible for the quality of information provided by the originating exception. So fine.
However, if your application uses some third party API, or worse, has a plugin framework against which third party developers can integrate anything, exception wrapping is essential for usability. Imagine you have an engine that initializes and executes plugins without knowing any of that plugin’s implementation details. What are the implications of such an environment?
- The engine doesn’t have compile-time access to every third party API for which a plugin may have been written.
- The engine has very little control over what operating system services a given plugin may use, and so cannot guess at which types of errors the plugin may fall prey to.
- The engine is the entry point and management hub for the application, and is therefore responsible for providing meaningful feedback to the user.
Given these, why not simply allow the plugin interface to throws Exception? Assuming the application wants to interpret HTTP-404 errors and say something like “The internet resource XXX cannot be found. Maybe your application is misconfigured.”, it will have to go to great lengths to determine which user-friendly error to match up with which implementation of java.lang.Exception. Also, this mapping is extremely brittle; if a new plugin is introduced, there is a good chance that user-friendly messages don’t exist for the errors it may introduce into the system. Yet another consequence is the need for each exception type to be accessible during compile-time for the engine (to allow if( e instanceof XXXException ) to work)…this means that the plugin development process now requires intimate interaction with engine development and release, which means that plugins aren’t plugins in this system any more.
Your argument at this point may be to say that no Java-based engine-plugin framework in existence today goes to these lengths or is restricted as fiercely as I say. My reply is: Show me one Java-based engine-plugin framework today that any system administrator – to say nothing of any average user – can troubleshoot effectively. As evidence of this effectiveness, please show me that the support forums are not crammed with interpretation of stack traces. Certainly JBoss, Weblogic, Websphere, and many others do not currently meet this requirement.
As an alternative, I think it’s best to have an interface for the plugin API that defines an invocation exception for the plugin to use in communicating to the engine. No, this isn’t my idea, but I do defend it. Maybe it starts out as just another wrapper for X exception from plugin-land, but at least it’s something that the engine knows about. As the framework matures, this exception can be modified to demand more triage on the part of the plugin developer. If used effectively, it gives the plugin developer a chance to interpret groups of exceptions that could occur at a given point in the plugin’s execution. At this point, the developer (who is an expert in the foreign API) can provide meaningful steps for troubleshooting that error. If the exception’s API is designed well, it virtually guarantees that good plugin citizens will provide the engine with enough information to:
- lookup the troubleshooting steps in an internal (or external) resource
- point the user at a support forum or troubleshooting guide online
- or, provide distilled information for the user to submit to developers
rather than just puking out a stack trace. This custom exception allows the engine developer to retain some control over the quality of information that comes out of a plugin, and to strongly suggest a best practice. While it doesn’t rule out abuse of the error handling that it embodies, it definitely makes the right thing the easier thing to do.
If you’re developing this kind of framework, please, please, please! use something other than throws Exception to convey errors out of your plugins. Think of it as insulation for your engine.
Adafruit
Instructables
Wikipedia