Exception Treatment REST Spring Services

Asked

Viewed 4,675 times

3

In a REST service application with Spring, where should the exception handling/release take place? In the Controller or Service?

Example 1 - Handle in Controller (In this case I’m only returning a badrequest as an example)

@GetMapping
public ResponseEntity<Objeto> consultar(String foo) {
    Objeto objeto;
    try {
        objeto = objetoService.findByFoo(foo);
        if (objeto != null) {
            return ResponseEntity.ok(objeto);
        } else {
            return ResponseEntity.notFound().build();
        }
    } catch (Exception e) {
        return ResponseEntity.badRequest().build();
    }
}

Example 2- Handle in Service

public Objeto findByFoo(String foo) throws Exception {
    Objeto objeto = objetoRepository.findByFoo(foo);
    if(objeto != null){
        return objeto;
    } else {
        throw new Exception();
    }
}

The data are only illustrative.
In case the service could be treating this Exception with a Controlleradvice through an Exceptionhandler of each exception.

What would be the most correct way to be working with exceptions?

  • In my opinion this should be dealt with in the Controller. Let’s imagine that at some point in the project the service method findByfoo need to return you a null object and take another logic, without being obligatory to play this exception. But this depends on case by case, let’s assume another situation, to register a certain entity X Oce needs to search for an entity Y and so so you can register X, in this case a treatment/exception launch in the service would be validated.

  • @Erickmaia, in this case, wouldn’t the Controller be just an input port for my data via REST? And the question of validation, even the one that gave example, where returns a null object and needs to take another logic, do not know something related to business rule that stays in service?

2 answers

3

Controller only manages the flow of information it should not contain business rules and persistence in its content.

It would be more interesting to treat the exceptions in the Service layer, so you would better manage future rule changes if you had to retrieve information from a DAO for example.

  • 1

    That’s what I ended up doing, but with a @Controlleradvice. Thank you.

2

As the handling of errors as well as others such as Logging, data access, etc... are called cross interests(cross Cutting Concerns), the most appropriate would be to treat the exceptions shot by means of a Aspect. Spring allows you to define a @ControllerAdvice that would centralize the treatment of exceptions triggered by Controllers.

Here is an example of error handling for ResourceNotFoundException:

@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {        

//....

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException rnfe,
            HttpServletRequest request) {

        ErrorDetail errorDetail = new ErrorDetail();
        errorDetail.setTimeStamp(new Date().getTime());
        errorDetail.setStatus(HttpStatus.NOT_FOUND.value());
        errorDetail.setTitle("Recurso não encontrado.");
        errorDetail.setDetail(rnfe.getMessage());
        errorDetail.setDeveloperMessage(rnfe.getClass().getName());

        return new ResponseEntity<>(errorDetail, null, HttpStatus.NOT_FOUND);
    }

//...

}

That class ErrorDetail is a class that can be customized to your application requirements:

public class ErrorDetail {

    private String title;
    private int status;
    private String detail;
    private long timeStamp;
    private String developerMessage;
    private Map<String, List<ValidationError>> errors = new HashMap<>();

//...
}
  • That’s what I did, I put all the exception handling on a @Controlleradvice. Thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.