31

I have three layer Spring web app: dao, service and controllers. A controller never calls directly the dao, it does it through the service layer. Right now, most of the time if there is dao exception (runtime) that is not handled, it'll be caught by a JSP showing an error message to the end user. Should service layer catch all dao exceptions and wrap them as service exceptions?

try {
   daoInstance.someDaoMethod();
} catch(DataAccessException dae) {
   throw new ServiceException("message", dae);
}

Let's suppose ServiceException is runtime as well and it's not handled neither. Is there any difference to just throw the DataAccessException instead of the ServiceException? I just thought that the presentation layer should not know about data access exception. But I don't see the point of catching unrecoverable exceptions just to wrap them.

3 Answers 3

23

I think an important factor is who your service clients are.

If your service layer is just an architectural boundary between layers in your own project, and the service client is within the same trust realm, then it is ok to relax things, and let unchecked exceptions bubble out to the controller layer, or the service client.

However, for public facing code; service that are consumed by a third party or customer, I think it is cleaner to wrap any unchecked exceptions with a service oriented exception, primarily for security concerns, secondly for loose coupling, and clean abstraction.

A data layer exception should never, directly make it all the way to an end user of a web application. It potentially contains internal information about your schema, your queries, line number information, variable or function names, etc. End user exceptions can be sanitized in a secure setting.

An external service client isn't concerned with your implementation detail, and can't handle unchecked exceptions anyway, as they are bug or environmental issues. In secure applications, database errors are simply not secure enough to propagate, OracleException - ORA-01234 - ... which might be the 3rd table that was inserted. The client should be allowed to deal with any checked/expected exceptions that it can handle, and treat everything else as a potential bug report. Your service contract should be an atomic, consistent, transactional abstraction. If it can't do anything about the exception, then the only useful thing left is to give you a bug report. You already have the ability to log the exception, so why burden your end user with the details? Your app can be monitored, so you already know about the unchecked exceptions before the users report them.

It is never ok to eat exceptions, nor am I a fan of checked exceptions, but I prefer to have a plan that is appropriate for the nature of the overall product.

1
  • 1
    I was all the way with you until. .." nor am I a fan of checked exceptions" checked exceptions have its purpose. especially in the examples you gave
    – Jeryl Cook
    Aug 13, 2020 at 18:46
16

No, you should not wrap DAO exceptions in a web application

It's a lot of noise in the code for zero benefit. DAO exceptions are unchecked exceptions for a good reason. The application code cannot do anything useful to recover from a DAO exception. The real problem is here:

... it'll be caught by a JSP showing an error message to the end user.

Fix this problem in one place instead of crapping up the entire code base.

You control how an uncaught exception is displayed to the user. Uncaught exceptions are due to application bugs or a failure in the underlying system. There's no reason to give the user any information about the reason his request could not be served. There's nothing the user can do. All you should do is serve a friendly error page.

N.B.: if you find yourself writing a lot of tedious code, for example, creating a bunch of catch blocks that simply wrap and re-throw, there is almost always a better solution.

1
  • Thanks for your answer. And yes, the jsp shows a custom message: "Oops, something went wrong". It doesn't show any information about the exception
    – Oscar
    Oct 23, 2014 at 15:34
10

The main reason one would use exception wrapping is to prevent the code in the business layer from having to know about every possible exception in the system. There are two main reasons for this:

  • Consistency: declared exceptions aggregate towards the top of the call stack. If you do not wrap exceptions, but instead pass them on by declaring your methods to throw them, you may end up with top level methods that declare many different exceptions. Declaring all these exceptions in each method back up the call stack becomes tedious.

  • Encapsulation: You may not want your top level components to know anything about the bottom level components, nor the exceptions they throw. For instance, the purpose of DAO interfaces and implementations is to abstract the details of data access away from the rest of the application. Now, if your DAO methods throw SQLException's then the code using the DAO's will have to catch them. What if you change to an implementation that reads the data from a web service instead of from a database? Then you DAO methods will have to throw both RemoteException and SQLException. And, if you have a DAO that reads data from a file, you will need to throw IOException too. That is three different exceptions, each bound to their own DAO implementation.

So, in short, the answer is yes!

1
  • 3
    JPA implementations (e.g. Hibernate) throw unchecked exceptions. They don't have to be declared or caught. Sep 11, 2015 at 3:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.