How to Rethrow an Exception Without Wrapping them
Javelin-Throwing.gif

Java forces checked exceptions to be caught or thrown, because of this some programmers dislike check exceptions and instead use unchecked exceptions. This article looks at when to use check verses uncheck exertions and considers what are the option in using check exceptions.

When using checked exceptions you are forcing the users of your method to think about handling the edge cases that cause your implementation to fail. When using RuntimeExceptions these edge cases are often too easily overlooked.

One case where it is good practice to throw a RuntimeException is when the user calls a method incorrectly. For example, a method can check if one of its arguments is incorrectly null. If an argument is null, the method might throw a NullPointerException, which is an unchecked exception.

As a rule, of thumb do not throw a RuntimeException because you cannot be bothered with handling check exceptions. If the client can reasonably be expected to recover from the exception then use a checked exception.

When you call a method that throws a check exception, you can either catch the exception and handle it yourself or if that's not possible you can declare that you also throw the exception and propagate the exception on. Unfortunately propagating the exception on can lead to a proliferation of throw declarations, as the exceptions propagate further and further up the call stack.

Another popular option is to wrap the checked exceptions. One downside of this, is it leads to large chains of a stack traces, this can be seen when calling Exception.printStackTrace(). Even with this downsides this is often my preferred stratagy. The wrapped exception should be a custom exception that describes the failure in terms of your problem domain. It is better to throw a domain spesific exception like CustomerNotAddedException rather than say SQLException. Throwing the SQLException is not good because you are exposing the internal workings of your implementation. Of course since CustomerNotAddedException wraps SQLException, the SQLException is still available for debugging.

Compile time checking of checked exceptions is an extremely useful and an invaluable language feature however sometimes it does get in the way.

There is another option, that is to throw a checked exception at run-time without the compiler or the bytecode verifier knowing about it. Yes, it is possible to throw a checked exception as though it was a run-time exception.

Sun provide some dangerous methods in the sun.misc.Unsafe class and one of these methods is, throwException();

Sun have gone out of their way to prevent you from using sun.misc.Unsafe . They have purposely written this class with a private constructor only. I'm going to show you the way to use it, but you should think very carefully before deploying this solution in production code.

public void aMethod () // no "throws" clause!
{
    UnsafeHolder.throwException(new Exception("some checked exception"));
}

in details this is

    // required to avoid startup issues with the security manager.
    static class UnsafeHolder {
        static final sun.misc.Unsafe unsafe;
 
        static {
            try {
                Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
                field.setAccessible(true);
                unsafe = (sun.misc.Unsafe) field.get(null);
            } catch (Exception e) {
                throw new AssertionError(e);
            }
        }
 
        private UnsafeHolder() {
        }
    }
 
    /**
     * Rethrow any throwable, even checked exceptions blindly.
     *
     * @param t
     * @return
     */
    public static InternalError rethrowException(Throwable t) {
        UnsafeHolder.unsafe.throwException(t);
        // should never get there.
        throw new InternalError();
    }

The use of re-throwing exceptions in this manner, is especially useful in aspect orientated programming (AOP), where you do not wish to change the identity of the exception by wrapping it.

Some do's and don't's with exceptions

1. Unless you have a very good reason to catch an exception, don't catch it.

2. If you can correct the problem implied by the exception. eat the exception, because you fixed it. However there are some exceptions that it is unwise to catch.

3. If you can provide additional information about the exception. catch the exception, and re-throw it as an inner exception with more information. This is a very good reason to catch an exception, but note that we are still re-throwing it.

4.Always try to catch specific exceptions. Avoid catching System.Exception whenever possible.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License