DEV Community

Gilson Silva
Gilson Silva

Posted on

Utilizando ProblemDetail no Spring para tratamento de erros

O Spring Framework oferece diversas formas de lidar com exceções e erros em APIs REST. Uma das abordagens mais modernas e recomendadas é o uso do ProblemDetail, que segue o padrão RFC 7807 para fornecer detalhes sobre problemas HTTP de forma estruturada e padronizada.

Neste artigo, vamos explorar como utilizar o ProblemDetail no Spring para tratar exceções e retornar respostas de erro mais informativas e padronizadas para o cliente.

O que é o ProblemDetail?
O ProblemDetail é uma classe introduzida no Spring para facilitar o tratamento de erros em APIs REST. Ele permite que você forneça informações detalhadas sobre o erro ocorrido, como o status HTTP, uma mensagem descritiva, e até mesmo propriedades adicionais, como o timestamp do erro ou a categoria do problema.

Exemplo de Uso
Vamos considerar um cenário onde estamos criando um planeta em uma API, mas o nome do planeta já existe no banco de dados. Nesse caso, uma exceção do tipo DataIntegrityViolationException será lançada, e queremos retornar uma resposta HTTP com status 409 Conflict e detalhes sobre o erro.

Teste de Integração
Primeiro, criamos um teste para garantir que, ao tentar criar um planeta com um nome já existente, a API retorne o status 409 Conflict.

@Test
@DisplayName("Create Planet with existing name return conflict")
void createPlanet_WithExistingName_ReturnConflict() throws Exception {
    when(service.create(any(Planet.class))).thenThrow(DataIntegrityViolationException.class);

    mockMvc.perform(post("/planets")
                    .content(mapper.writeValueAsString(PLANET_REQUEST))
                    .contentType(APPLICATION_JSON))
            .andExpect(status().isConflict());
}
Enter fullscreen mode Exit fullscreen mode

Tratamento da Exceção com ProblemDetail
Para capturar a exceção DataIntegrityViolationException e retornar uma resposta detalhada, utilizamos o @ExceptionHandler no Spring. O ProblemDetail nos permite fornecer informações adicionais sobre o erro, como o título, detalhes, e até mesmo propriedades personalizadas, como o StackTrace e o TimeStamp.

@ExceptionHandler(DataIntegrityViolationException.class)
public ProblemDetail handleConflict(DataIntegrityViolationException ex) {
    var problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.CONFLICT, ex.getLocalizedMessage());
    problemDetail.setTitle("Dado informado já existe");
    problemDetail.setDetail("É preciso informar um dado válido");
    problemDetail.setProperty("StackTrace", ex.getStackTrace());
    problemDetail.setProperty("Categoria", "API");
    problemDetail.setProperty("TimeStamp", Instant.now());

    return problemDetail;
}
Enter fullscreen mode Exit fullscreen mode

Explicação do Código

  • @ExceptionHandler(DataIntegrityViolationException.class): Este método será chamado sempre que uma exceção do tipo DataIntegrityViolationException for lançada.
  • ProblemDetail.forStatusAndDetail(HttpStatus.CONFLICT, ex.getLocalizedMessage()): Cria um objeto ProblemDetail com o status HTTP 409 Conflict e a mensagem de erro da exceção.
  • setTitle e setDetail: Definem o título e os detalhes do problema, que serão exibidos na resposta.
  • setProperty: Adiciona propriedades personalizadas ao ProblemDetail, como o StackTrace, a categoria do erro e o timestamp do momento em que o erro ocorreu.

Resposta Esperada
Quando a exceção for lançada, a API retornará uma resposta no seguinte formato:

{
  "type": "about:blank",
  "title": "Dado informado já existe",
  "status": 409,
  "detail": "É preciso informar um dado válido",
  "instance": "/planets",
  "StackTrace": [...],
  "Categoria": "API",
  "TimeStamp": "2023-10-05T14:48:00Z"
}
Enter fullscreen mode Exit fullscreen mode

Conclusão
O uso do ProblemDetail no Spring permite que você forneça respostas de erro mais detalhadas e padronizadas, melhorando a experiência do consumidor da API e facilitando a depuração. Além disso, o ProblemDetail é altamente personalizável, permitindo que você adicione informações específicas sobre o erro, como o StackTrace e o TimeStamp.

Top comments (0)