What?
There are various reasons when we have to wrap java exceptions. Often those reasons are called: Checked Exceptions. According to the definition there are 2 types of exceptions:
But Why?
In practice using checked exceptions will lead to undesired behavior. Here are a few scenarios:
Let’s assume we have to use a method called getProperty(String key) throws SQLException defined in DBConfig to read a color property from the database and then to display it on screen. We instantiate the config object and then invoke the method. For avoiding a compiler exception we’ll add a throws SQLException to our method declaration. And then imagine that you have to add another one to the method invoking the method we wrote. The more mothods are involved the more checked exceptions added to the method declaration. It doesn’t make sense for a method called paintScreen to force you to handle excpetions like SQLException or IOException, doesn’t it?
Now we are going to add an interface named IConfig. We’ll have the existing class DBConfig and we’ll create another one FileConfig. The first one will throw SQLException and the second one IOException. If we’ll have too many checked exceptions we’ll pollute the interface with exceptions that might depend on implementation, inducing a tight coupling in our classes: the abstraction depends on modules exceptions. Pretty bad, isn’t it?
Now the bad practice: We’ll not going to use throws declaration. Not at all, because it generates too many problems. So let’s just try, catch, printstacktrace and that’s it. We’ll see later what to do. This is fast. This practice is again bad, because it just hide the problems. Especially in large applications with many programmers they tend to forget about the caught exceptions and real problems are not discovered. After all remember that exceptions are meant to signal a real abnormal behavior of the application.
There is also another reason that make us wrapping exceptions which is not related to checked or unchecked exceptions. Sometimes we simply want to hide and separate the implementation details from the exposed interface in order to reduce the complexity and to simplify the interface.
Ok, then. But How?
We have 2 simple options:
There is a very thin line between those 2 options and you have to understand it very well. First of all let’s think about it. The module which invokes the code throwing exceptions will have the wrapped class in the class path? If the response is definitely an yes then go for second point, otherwise choose the first one.
For example a client invokes remotely your api using rmi. The api throws the exception wrapped but the client have only the wrapper exception class in the classpath, not the wrapped one. An exception will be thrown. In cases like this one runtime exception should be created containing a descriptive message and should not wrap the original exception.
3 Responses
Mike
27|Aug|2008 1When you wrap an exception, you should try to provide at least as much information as the original exception, if not more. Don’t forget to include all of the original exception’s meta data, and consider adding your own.
Torgny Andersson
27|Aug|2008 2To me, the best solution is to wrap the exception thrown AND provide an additional description of what went wrong. Example:
StartupException["Failed to configure application.", ConfigurationException["Failed to open configuration file: something.conf", IOException["file not found"]]]
This has two benefits:
1) The exception description is very general at the top and is more and more detailed for the wrapped exception, which makes it easier to put the originating exception into a context.
2) The entire stack-trace is kept, which makes it easier to track down the problem.
owen
26|Sep|2008 3I’ve always found exceptions to be heavily mis-used often like goto statements replacing proper logic blocks and good coding practices.
Leave a reply