1
+-------------+         +--------+        +----------+
| repository  +-------->+service +------->+controller|
+-------------+         +-^------+        +------------+
+-------------+           |  +^  ++------>+controller2 |
| repository2 +-----------+  |    |       +------------+
+-------------+              |    +------>+controller3 |
+------------+               |            +------------+
| repository3+---------------+
+------------+

I want to be able to support multiple different implementations of my repository interface. I use my interface in by business service and I can select what ever implementation I want. So far so good.

When I try to insert multiple entries with the same key, db connector will throw an exception. In case of jdbcTemplate, this will be DuplicateKeyException, in case of Hibernate, this will likely be some kind of Constraint Exception. Not ideal, but still good enough.

I must be able to tell the service consumer what exactly went wrong any why, where passing the exception is not good enaugh (as in response 500). Getting muddy.

So my options are either to catch that exception in the controller, which then I have to implement in each controller (which seems muddy waters to me), or, I can throw some kind of exception in the business service (which seems better) and then handle that in the controller. I think this is better because then I'll be catching my own one of a kind exception, and I'm sure what's going on.

The problem is, most of my business service implementation is actually an existing interface implementation, which means that in order to do this, I have to override the interface I'm using with new declarations which will have exceptions. This is not what I want.

What is the proper way to handle this kind of situation? I'm using Spring but I would like a more general answer.

6
  • 1
    Just forward the entire exception and stack trace to the client via a JSON payload. That shouldn't be too hard to do; presumably some sort of exceptions bubble up to the controllers, otherwise how would you know to respond with 500? May 14, 2020 at 18:32
  • but clients need to know why their db inserts aren't passing. right? May 14, 2020 at 18:34
  • The exception doesn't tell you that? May 14, 2020 at 18:34
  • If your response needs an ordinary, human-readable error message, you have no choice; you must catch the exception and translate it into plain English for the response. May 14, 2020 at 18:35
  • but if I don't handle this exception in the controller, client is just going to get internal server error 500, right? And what about when client tries to do bulk insert, some things pass, others don't? May 14, 2020 at 18:36

1 Answer 1

1

Interfaces

Aren't just about method signatures. They are also about the exceptions that can be thrown across them.

So the simple answer is that each of your repositories needs to catch their own exceptions,and then translate them into an acceptable exception to throw across the interface.

The controllers will then need to catch the translated exceptions, and because the translated exceptions will follow one convention, they need only catch a (for example) DuplicateKeyException and then respond indicating the error that occurred. So if its a simple language response, plain English (or whatever the human speaks). If its a semantic error, hopefully there is a code for Duplicate Key.

3
  • this sounds like a way to go, but what about e.g. hibernate where actual implementation is created at runtime? May 15, 2020 at 5:23
  • 1
    @poppycockears Wrap it. Unless you are adapting everything to use the hibernate interface?
    – Kain0_0
    May 15, 2020 at 6:11
  • Well no, I don't see a reason why I should be doing that. So wrapping is OK! Thnx a lot May 21, 2020 at 5:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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