DEV Community

Diego Moreira
Diego Moreira

Posted on

Como personalizar o retorno das exceptions no seu projeto Spring Boot

Quando utilizamos APIs Rest com Spring Boot e lançamos exceptions, se torna extremamente útil que a apresentação desses erros seja personalizada para que fique mais clara a compreensão dessas informações por parte de seus consumidores, sendo assim, neste post vou comentar um pouco sobre a anotação @ControllerAdvice que pode ser usada juntamente com a anotação @ExceptionHandler para fazer essa personalização.

Definição das anotações:

  • @ControllerAdvice: é uma anotação usada para lidar com todas as exceções lançadas no projeto que usa Spring Boot
  • @ExceptionHandler: esta anotação serve para interceptar/manipular o tipo de exceção que for declarado juntamente com ela, assim pode ser criado um DTO para ser um "padrão" de retornos para as exceptions do projeto

Exemplos da implementação

DTO que tem os campos que serão retornados quando uma exception for lançada:

package config.exceptions;

import lombok.Builder;
import lombok.Getter;

import java.time.LocalDateTime;

@Builder
@Getter
public class StandardErrorDto {

    private LocalDateTime timestamp;
    private Integer status;
    private String error;
    private String path;
    private String type;
}
Enter fullscreen mode Exit fullscreen mode

Classe ResourceExceptionHandler que faz uso da anotação @ControllerAdvice

package config.exceptions;

imports ...

import java.time.LocalDateTime;

@ControllerAdvice
public class ResourceExceptionHandler {

    @ExceptionHandler({ Exception.class })
    public ResponseEntity<StandardErrorDto> handleAll(Throwable ex) {

        StandardErrorDto apiError = StandardErrorDto.builder()
                                              .status(getResponseStatus(ex).value())
                                              .timestamp(LocalDateTime.now())
                                              .error(ex.getMessage())
                                              .type(ex.getClass().getName())
                                              .build();

        return ResponseEntity.status(apiError.getStatus()).body(apiError);
    }

    private HttpStatus getResponseStatus(Throwable exception) {
        ResponseStatus responseStatus = exception.getClass().getAnnotation(ResponseStatus.class);
        if (exception.getClass().getAnnotation(ResponseStatus.class) == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return responseStatus.value();
    }
}

Enter fullscreen mode Exit fullscreen mode

Além do exemplo acima existem diversas outras exceptions que podem ser interceptadas e ter seus retornos modificados, como por exemplo quando é usada a dependência do spring-boot-starter-validation mas isso pode assunto para uma nova postagem.

Top comments (0)