I have done something very similar. But first, you do not need to relay what the error is to the user, at all. It makes no sense to tell them how the error occurred since you will be logging it anyway. (Does it make sense if the user knows the error occurred because of a NPE or an IO error, even if you rename it to more 'friendly' terms) ?
First you may want to consider re-throwing all of your Exceptions as runtime (unchecked) exceptions. This will force errors to be logged centrally and consistently. Else you will have to hope that each and every instance of your error handling code will log it correctly. To re-throw your SQLExceptions for example:
try{
conn.close();
} catch(SQLException ex){
//logger.error("Cannot close connection"); //don't log this here, do it centrally
throw new RuntimeException(ex);
}
You will want to forward the users to a general error page simply telling them an error has happened. This indicates to them that whatever they were doing wasn't processed. This is very important so that they don't hit back and keep trying to enter a payment over and over again. let them know something has gone wrong and to either (a) contact the helpdesk or (b) place a form inside the default error page that can log a ticket or send an email to the helpdesk. To accomplish this you will need to define this in your web.xml:
<error-page>
<error-code>500</error-code>
<location>/Error.jsp</location>
</error-page>
Next, inside the error.jsp page (or servlet), log the error here if your container allows you to reference the stack trace as request.getAttribute("javax.servlet.error.message"));
.
OR, create a filter that acts only on the response, and like the following:
try {
chain.doFilter(req, res);
} catch (Exception e) {
logger.error("pass any Mapped Diagnostic Context here", e); //log here, centrally
throw new RuntimeException(e); //throws back to the container so that the error page will be seen
}
This will catch all propagated exceptions (unchecked and uncaught), log them, then re-throw them so that they invoke the error page. This will make error reporting
- Accurate (one log per instance of an error)
- Reliable (if the user received the error, you receive the logging details
- Consistent (standardized if you implement re-throwing checked exceptions as unchecked, you will be able to see all exceptions and also prevent users from trucking along into error-prone territory, where you risk disastrous data-cleanup missions because they inserted crap into tables or left key tables unpopulated)
Finally, you may want to consider using log4j and using an appender that outputs to somewhere you can review errors without having to wait on the operations teams to send them to you. Much easier that way if you are routinely maintaining the application.