I am using DAO pattern for one of my application and have following sequence
1. Action Class calls DAOFactory Class
2. DAOFactory Class calls DAO Class
3. DAO Class calls ServiceLocator Class.
4. ServiceLocator Class return data source.
5. DAO class uses data source to do all other operations.
Now I have try catch block in every class.
1. ServiceLocator have "Context initialization failure" and "JNDI setup failure"
2. DAO have SQLExceptions
3. DAOFactory have "Class initilization failure" and
4. Action class have custom failures.
Now I want to manage the exceptional handling so that end user and debugger will have useful information. I want to make sure for every exception user will get meaning information rather than root cause type error in web page.
So for that can anyone suggest which and how I catch and carry on to other level? how can i have meaning error message for user as well as preserving error from the system.
Primary responsibility of the layer is to insure that resources (result set, statement, connection) are correctly handled in all situations.
Secondary responsibility of the layer is to return errors to the caller so that the caller can do whatever it wants with it. Differentiating the types of errors are driven by business requirements.
Your layer doesn't seem to have anything to do with a user nor web page. The fact that the system/app has that is irrelevant because it is the responsibility of the caller (or callers above the caller) to correctly handle what other layers do. So there is at least one layer between your database layer and everything else and that layer is responsible for dealing with the database layer errors.
I strongly suggest that you do not propagate layer specific exceptions through other layers. Myself that means that normally I do not propagate SQLExceptions out of the database layer because that exception is part of the JDBC layer and not the database layer.
In terms of the system and the database used by the system errors can be broken into the following
1. Database is 'down'
2. Invalid user (caller) data. Where the user (caller) sent bad data.
3. Invalid use case. Where the user (caller) did something that invalidated a business rule.
4. All other errors. This would be something like if a system update failed to install a needed proc.
An example of case 2 is where a user (caller) sends order with a delivery date which is in the past.
An example of case 3 is where the user (caller) sends a new customer down which 'duplicates' a previous customer (definition of a duplicate is business rule driven.)
For example if a user is trying to enter a new customer and the database is down then the system, should be capable of providing the following functionality
1. Some way to cancel
2. Some way to preserve the data until the database is back up.
3. Sufficient information and process for a user to proceed to tell someone (or do something) about the database being down.
But as an alternative to database is down is that the caller could be an automated process that is trying to do an scheduled task. In that case the caller must react by sending an appropriate notification and then rescheduling the task (or taking some other appropriate action for the task.)
As another example case 4 is always basically a catastrophic failure that is unlikely to be resolved immediately. But processes should exist for that as well. So the user (human at a GUI) should have enough information to know that it isn't something that is going to fix itself and also have enough information that it allows someone else to track down the problem.
Case 4 is also the hardest to diagnose in a production system which is why I always use logging. In database layers and other layers as well. What I do in situations like this is to log the exception, enough information to identify the location and relevant runtime details and a guid. Then I create a custom exception with message text that includes the guid. The caller is responsible for propogating to the respective user.