
Originally Posted by
constv
The only factor that should determine where to handle errors in your application is the specific requirements of your application. In other way, based on what behavior of the application you need in case of any errors (including some specific cases), you should decide which module in your application has the sufficient contextual knowledge to handle any specific error, or all errors in general. This generally means that all exceptions in your Middle tier (Services/DAOs) must freely propagate to the application tier (front-end) that would ultimately handle them. To ensure that, as shahnawazshahin has pointed out, all your exceptions must be unchecked (extend RuntimeException.) This means that you may have to catch any checked exceptions in your services, wrap them into clarifying RT exceptions with added messages, and re-thrown - only to be caught and handled by the designated handlers on the front-end, since only the latter would know what exactly the application wants to do with those errors. In some cases, you may even catch, wrap, and re-throw a RTE - if you think you can add valuable information to it on the way. But no matter what, never discard the original exception, never replace the valuable stack trace with your error message, etc. Always keep the full original stack trace and nested exceptions, because they provide the most important info about the source of the error.