Some notes on Exception Handling in Java!

Mostly copy / paste with sources linked..

Notes from this page...
  • Checked Exceptions are exceptions that must be declared in the throws clause of a method. 
  • A checked exception indicates an expected problem that can occur during normal system operation such as problems communicating with external systems, and problems with user input. 
  • Often, the correct response to a checked exception is to try again later, or to prompt the user to modify his input.
  • Unchecked Exceptions are exceptions that do not need to be declared in a throws clause. 
  • They extend RuntimeException. 
  • An unchecked exception indicates an unexpected problem that is probably due to a bug in the code. 
  • The most common example is a NullPointerException. 
  • An unchecked exception probably shouldn't be retried, and the correct response is usually to do nothing, and let it bubble up out of your method and through the execution stack. Eventually, at a high level of execution, the exception should probably be logged.


Creating Your Own Exceptions

Most packages and/or system components should contain one or more custom exception classes.
There are two primary use cases for a custom exception.
  • Your code can simply throw the custom exception when something goes wrong. 
For example:
throw new MyObjectNotFoundException("Couldn't find object id " + id);
  • Your code can wrap and throw another exception. 
For example:
catch (NoSuchMethodException e) { 
    throw new MyServiceException("Couldn't process request", e); 
}
Wrapping an exception can provide extra information to the user by adding your own message (as in the example above), while still preserving the stack trace and message of the original exception. It also allows you to hide the implementation details of your code, which is the most important reason to wrap exceptions.
Look at the Hibernate API. Even though Hibernate makes extensive use of JDBC in its implementation, and most of the operations that it performs can throw SQLException, Hibernate does not expose SQLException anywhere in its API. Instead, it wraps these exceptions inside of various subclasses of HibernateException. Using the approach allows you to change the underlying implementation of your module without modifying its public API.
Notes from here.
Remember these:
  • If the client can take some alternate action to recover from the exception, make it a checked exception. If the client cannot do anything useful, then make the exception unchecked.
  • Never let implementation-specific checked exceptions escalate to the higher layers. For example, do not propagate SQLException from data access code to the business objects layer. Business objects layer do not need to know about SQLException. You have two options:
Convert SQLException into another checked exception, if the client code is expected to recuperate from the exception.

Convert SQLException into an unchecked exception, if the client code cannot do anything about it.

  • Try not to create new custom exceptions if they do not have useful information for client code.
  • Do not suppress or ignore exceptions
When a method from an API throws a checked exception, it is trying to tell you that you should take some counter action. If the checked exception does not make sense to you, do not hesitate to convert it into an unchecked exception and throw it again, but do not ignore it by catching it with {} and then continue as if nothing had happened.
  • Do not catch top-level exceptions
Unchecked exceptions inherit from the RuntimeException class, which in turn inherits from Exception. By catching the Exception class, you are also catching RuntimeException as in the following code:
try{
..
}catch(Exception ex){
}
The code above ignores unchecked exceptions, as well.
Lets move on.
  • Throw exceptions for error conditions while implementing a method. E.g. if you return -1, -2, -3 etc. values instead of FileNotFoundException, that method can not be understand.
  • Use types of exceptions clearly. Fatal: System crash states. Error: Lack of requirement. Warn: Not an error but error probability. Info: Info for user. Debug: Info for developer. 
  • Don't absorb exceptions with no logging and operation. Ignoring exceptions will save that moment but will create a chaos for maintainability later.
  • Only catch exceptions if we can: (a) do something about it (correct/recover/log); (b) need to add information; or, (c) need to swallow it (rare, but it happens).