diff --git a/src/main/java/com/bts/personalbudget/exception/ControllerExceptionHandler.java b/src/main/java/com/bts/personalbudget/exception/ControllerExceptionHandler.java index 6bd9fb4..fc240ff 100644 --- a/src/main/java/com/bts/personalbudget/exception/ControllerExceptionHandler.java +++ b/src/main/java/com/bts/personalbudget/exception/ControllerExceptionHandler.java @@ -11,6 +11,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; @@ -22,6 +23,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; +@Slf4j @RestControllerAdvice public class ControllerExceptionHandler { @@ -94,4 +96,12 @@ public ResponseEntity handlerFolderNotFoundException(MethodA HttpStatus.BAD_REQUEST); } + @ExceptionHandler(Exception.class) + public ResponseEntity handleGenericException(Exception exception) { + log.error("m=handleGenericException, message={}", exception.getMessage(), exception); + return new ResponseEntity<>( + new ErrorResponse("Erro interno no servidor"), + HttpStatus.INTERNAL_SERVER_ERROR); + } + } diff --git a/src/main/java/com/bts/personalbudget/exception/ErrorResponse.java b/src/main/java/com/bts/personalbudget/exception/ErrorResponse.java new file mode 100644 index 0000000..99486d9 --- /dev/null +++ b/src/main/java/com/bts/personalbudget/exception/ErrorResponse.java @@ -0,0 +1,6 @@ +package com.bts.personalbudget.exception; + +public record ErrorResponse( + String message +) { +} diff --git a/src/test/java/com/bts/personalbudget/exception/ControllerExceptionHandlerTest.java b/src/test/java/com/bts/personalbudget/exception/ControllerExceptionHandlerTest.java new file mode 100644 index 0000000..3b2188b --- /dev/null +++ b/src/test/java/com/bts/personalbudget/exception/ControllerExceptionHandlerTest.java @@ -0,0 +1,55 @@ +package com.bts.personalbudget.exception; + +import com.bts.personalbudget.controller.validation.ValidationResponse; +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MissingServletRequestParameterException; +import static org.assertj.core.api.Assertions.assertThat; + +class ControllerExceptionHandlerTest { + + private final ControllerExceptionHandler handler = new ControllerExceptionHandler(); + + @Test + @DisplayName("Deve retornar 500 com mensagem genérica para exceção não mapeada") + void shouldHandleGenericException() { + final RuntimeException exception = new RuntimeException("erro interno inesperado, com dados sensíveis"); + + final ResponseEntity response = handler.handleGenericException(exception); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); + assertThat(response.getBody()).isNotNull(); + assertThat(response.getBody().message()).isEqualTo("Erro interno no servidor"); + assertThat(response.getBody().message()).doesNotContain("dados sensíveis"); + } + + @Test + @DisplayName("Deve retornar 400 para InvalidFieldsException") + void shouldReturnBadRequestForInvalidFieldsException() { + final InvalidFieldsException exception = new InvalidFieldsException( + "Campos inválidos", String.class, Map.of("campo", "mensagem")); + + final ResponseEntity response = handler.handleJsonErrors(exception); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + assertThat(response.getBody()).isNotNull(); + assertThat(response.getBody().validations()).containsEntry("campo", "mensagem"); + } + + @Test + @DisplayName("Handler específico de MissingServletRequestParameterException deve continuar funcionando sem regressão") + void shouldStillHandleMissingParameterExceptionSpecifically() { + final MissingServletRequestParameterException exception = + new MissingServletRequestParameterException("param", "String"); + + final ResponseEntity response = handler.handlerFolderNotFoundException(exception); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + assertThat(response.getBody()).isNotNull(); + assertThat(response.getBody().validations()).containsKey("param"); + } + +}