Do not catch unchecked exceptions
Exceptions in java can be divided into checked and unchecked exceptions. Java compiler would force you to catch the checked exceptions but not the unchecked exceptions. Unchecked exceptions includes error and Runtime exception. These are the conditions in which program will not be able to handle the flow even if these are caught, so better let the JVM throw error and print stack rather than trying to handle these.
Error- A condition which occurs outside the program and causes failure, example, hardware failure.
Runtime Exceptions- An exception condition which occurred because of bad programming practice or unexpected input from user. For example, null value assigned to a variable being used or division by zero. Ideally these errors should be handled by code checks and not exception handling.
This means we should avoid catching superclass Exception as that will cover RuntimeExcpetions
Throw more relevant exceptions
Exception handling is done at multiple levels in code. For example you have, action->Process->Data layer. Now you might catch an exception in Database layer, but you might want to handle the exception actually in Action layer. So rather than throwing back filenotfound or sqlexception, you can create a DAOException and throw it instead. which will travel through Process layer and then to Action. This will help Action to handle fewer exceptions which are relevant at that layer.
Caveat- You might want to make sure you are passing all the relevant information back to the upper layers.
Using multiple try-catches
Instead of using one big block of try catch, create multiple blocks for better handling of exceptions. Make sure to take care of flow, once an exception is handled, the code will move to next try block.
Handle Exceptions late in code flow
Throw exceptions back to higher layers rather than absorbing them at lower layers. E.g. If an exception is caught at DAO layer, you might still want to throw it back to action layer for better handling.
Extend Exception and not Throwable
Here is the hierarchy of Exception class structure. Ideally we should try to extend a class as low as possible in hierarchy
Throwable->Exception and Error
Exception-> RuntimeExceptions and [other exceptions like filenotfound]
RuntimeException-> ArtithmeticException, NullPointerException