Question

I'm developing an application that has a backend (Java, Spring) and a frontend (TypeScript, Angular). The backend application provides with an OpenAPI-compatible API and performs certain operations with different 3rd-party services (Kubernetes cluster, GitLab server and other ones).

The backend service has controllers, they call services, they call repositories, they call clients. So, for example, when a frontend application needs to delete some object (for example, a pod) from a Kubernetes cluster, it sends the following request to the server: DELETE /api/v1/workload/pod/name/blah-blah-blah. the controller has a separate method that proceeds this request and it calls the corresponding service that is responsible for pod-related operations. The service calls the repository that is responsible for pods. The repository calls an internal Kubernetes client (actually a wrapper). The client calls a 3rd-party library (the original Kubernetes client) which performs the actual communication with the Kubernetes cluster.

What do you think, where should I catch the exception from the original Kubernetes client if it's being raised? For example, if there is no object with such a name in the cluster? What layer should handle it - a controller, a service, a repository or a client? Obviously, the application needs to catch this exception to reply with the 404 code instead of replying with 500?

Thanks in advance for any suggestions and sorry if my question is not fully clear.

Was it helpful?

Solution

There are two reasons for catching an exception

  1. To convert the exception to a different exception, so that internal implementation details are not exposed to users of a module. An example could be that you want to turn a Kubernetes "no such pod" exception into a more generic Repository exception "item not found". These catch clauses should be within the module at a point where it is logical to have knowledge of both the source and target exception types.

  2. To handle the exception, where handling can also mean informing the user that the operation they requested could not be completed. These catch clauses should be at a point where the exception can be meaningfully handled. If the handling is just informing the user, then that would most logically be within the Controller.

OTHER TIPS

There is only one reason to catch An Exception - to do something "useful" with it.

Question: Do you "screen" every telephone call that comes into your office building on the off-chance that it might be relevant to you and "throw back" [all] the ones that aren't? Of course not.

It's the same with Exceptions.
Catch those that you can usefully handle and ignore all the others (let them propagate up the call stack) for some other code to deal with. This is why people create custom Exception classes, because it makes it easier to catch the right ones.

Bart's second scenario is, in my opinion, two separate cases.

  • Dealing with (and, therefore, getting rid of the Exception) is the preferred option.

  • Giving up and telling the User "something went wrong" (much more that will only scare them) is a back-stop position that you need to have, but is really too late (being too far removed from the site of the problem) to do anything really "useful".

Licensed under: CC-BY-SA with attribution
scroll top