I'm developing a MVC Web application with a REST interface.

The REST controller performs actions on persisted items through a service class, which translates exceptions coming from the persistence layer.

When a request involves an item that not exists in the database, I would like to return 404 code, but actually this is not possible due to the exception translation operated by the service, that prevents the controller from knowing the reason of the problem.

Should the service class return a particular exception only for this case? Conversely, should the controller check for item existence before any action?

  • 3
    "but actually this is not possible due to the exception translation" - can you elaborate on why this isn't possible ? Most web frameworks allow you to respond 404 in some way (raise a specific exception, controller returns a certain value, etc.) Which exception comes out of the service class is kind of irrelevant to this, you can always catch it, right ? – guillaume31 Jan 13 '16 at 9:36
  • Right. Edited with more details. – aleric Jan 13 '16 at 9:46
  • 1
    Shouldn't the controller be able to know what exception was thrown? This seems like a bad design. – gardenhead Jan 13 '16 at 10:14
  • I think that bad design would be letting an exception thrown in the persistence layer reach the controller without adding relevant context (that could come from the service), hence the exception translation. – aleric Jan 13 '16 at 11:17

The Service layer can translate exception received from lower layers to avoid coupling between the controller and the persistence layer. But in doing that translation, the Service layer should not throw away/obscure information that could be relevant for dealing with the reported error.

So, the Service layer should in general have a one-to-one mapping between persistence exceptions and the exceptions they get translated into. You should only deviate from that if the persistence layer, for legacy reasons, throws two different exceptions for one and the same problem.

| improve this answer | |
  • Seems reasonable. But would be difficult to map all the exception that the persistence layer could throw. I think I'll go mapping only exceptions that one expects a service to throw (object not found, already exists, etc.) and translate anything else into a more generic "service exception". – aleric Jan 14 '16 at 8:52
  • @aleric: Be careful that you don't lump stuff together that needs different treatment when handling the error. Otherwise, that is a reasonable way to start. – Bart van Ingen Schenau Jan 14 '16 at 11:46

In most applications, the Service would retrieve the object it needs through the data access layer (effectively loading it in memory) before it can modify it and save it back.

If the object doesn't exist, the data access object would probably return null. I would maybe not raise an exception at that point but at least return a specific error case value. The Controller would get it and respond with a 404.

| improve this answer | |
  • The data access layer throws an unchecked exception (I'm using Spring's JdbcTemplate), that, as I said, gets translated by the service. I would not consider returning error values anyway, since I'm programming in Java. – aleric Jan 13 '16 at 13:50
  • What prevents you from translating that exception too ? Do you have control over what happens in the service at all ? And I'm not talking about your C-like integer error codes but a real [special case error object].(martinfowler.com/eaaCatalog/specialCase.html) – guillaume31 Jan 13 '16 at 14:03
  • Plus, a Data Access Object or Repository should probably be here to translate from the world of low-level data access stuff to the world of your business objects. In the case of the database throwing because the data was not found, it should probably catch it and return null. – guillaume31 Jan 13 '16 at 14:11
  • That's the point. Translating that exception too, will cause the controller to miss the reason of the exception, losing the chance to know that the object is not found. – aleric Jan 13 '16 at 14:50
  • Thanks for citing the special case object (try to remove the dot between parenthesis to get the link working). – aleric Jan 13 '16 at 14:54

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.