Search code examples
springrestspring-bootmicroservices

Throw Exception through multiple services


I have a little microservice architecture with 3 depending services. Each service represents a seperate Spring Boot project. If an exception occurs on the lowest level of the architecture I would like to throw it through all other services up to the highest/user endpoint service.

Each service API returns a HttpEntity(Response Entity) including a specific object. I found a lot of possible solutions like ResponseEntityExceptionHandlers but all examples shown for a single service architecture without multiple depending services.

Are there any best practices how to throw an Exception through multiple services with Spring Boot?


Solution

  • Assuming that you have three services A (relates directly on B), b (relates directly on C) and C and user calls your service A, but it can be applied to any number of services.

    I will briefly describe you the approach

    If error occurs in the service C (exception thrown), your code should catch Exception and return a meaningful response. Simplest I can think of would be a @ControllerAdvice

    @ControllerAdvice
    public class GlobalExceptionHandler {
    
          @ExceptionHandler(YourException.class)
          public ResponseEntity<ApiErrorDto> handleYourException(YourException e) {
          return ResponseEntity
                .status(HttpStatus.BAD_REQUEST) //or any other suitable 
                .body(new ApiError(e.getMessage());
         }
    }
    

    ApiError could be just a basic POJO class with a single field holding the message, or any other field meaningful for your exception handling.

    Now when your service B receives response it should check whether it is expected status code or an error status code and act accordingly.

    Your ApiError class should be shared between all services so that it can be easily serialized/deserialized everywhere. That way once you receive error you can decide what to do next, one of the scenarios could be throwing another exception to be caught by ExceptionHandler in service B.

    It's a starter, you can decide whether you want to return a string message in your ApiError, or maybe some kind of a meaningful code etc. Bottom line is that you should include that information in the response of the service where error occurs and interpret that information in the calling service.