diff --git a/src/main/java/org/springframework/samples/petclinic/rest/advice/ExceptionControllerAdvice.java b/src/main/java/org/springframework/samples/petclinic/rest/advice/ExceptionControllerAdvice.java index a49745d009c389af72bbf23a7d1cddf61f88fed3..a01b1ebc8bf916c1cd4dd74651a9db8418f963f6 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/advice/ExceptionControllerAdvice.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/advice/ExceptionControllerAdvice.java @@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.rest.advice; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -33,53 +34,76 @@ import org.springframework.web.context.request.WebRequest; import static org.springframework.http.HttpStatus.BAD_REQUEST; /** + * Global Exception handler for REST controllers. + * <p> + * This class handles exceptions thrown by REST controllers and returns + * appropriate HTTP responses to the client. + * * @author Vitaliy Fedoriv + * @author Alexander Dudkin */ - @ControllerAdvice public class ExceptionControllerAdvice { - @ExceptionHandler(Exception.class) - public ResponseEntity<String> exception(Exception e) { - ObjectMapper mapper = new ObjectMapper(); - ErrorInfo errorInfo = new ErrorInfo(e); - String respJSONstring = "{}"; - try { - respJSONstring = mapper.writeValueAsString(errorInfo); - } catch (JsonProcessingException e1) { - e1.printStackTrace(); + /** + * Record for storing error information. + * <p> + * This record encapsulates the class name and message of the exception. + * + * @param className The name of the exception class + * @param exMessage The message of the exception + */ + private record ErrorInfo(String className, String exMessage) { + public ErrorInfo(Exception ex) { + this(ex.getClass().getName(), ex.getLocalizedMessage()); } - return ResponseEntity.badRequest().body(respJSONstring); + } + + /** + * Handles all general exceptions by returning a 500 Internal Server Error status with error details. + * + * @param e The exception to be handled + * @return A {@link ResponseEntity} containing the error information and a 500 Internal Server Error status + */ + @ExceptionHandler(Exception.class) + public ResponseEntity<ErrorInfo> handleGeneralException(Exception e) { + ErrorInfo info = new ErrorInfo(e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(info); + } + + /** + * Handles {@link DataIntegrityViolationException} which typically indicates database constraint violations. + * This method returns a 404 Not Found status if an entity does not exist. + * + * @param ex The {@link DataIntegrityViolationException} to be handled + * @return A {@link ResponseEntity} containing the error information and a 404 Not Found status + */ + @ExceptionHandler(DataIntegrityViolationException.class) + @ResponseStatus(code = HttpStatus.NOT_FOUND) + @ResponseBody + public ResponseEntity<ErrorInfo> handleDataIntegrityViolationException(DataIntegrityViolationException ex) { + ErrorInfo errorInfo = new ErrorInfo(ex); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorInfo); } /** * Handles exception thrown by Bean Validation on controller methods parameters * * @param ex The thrown exception - * @param request the current web request + * * @return an empty response entity */ @ExceptionHandler(MethodArgumentNotValidException.class) - @ResponseStatus(code = BAD_REQUEST) + @ResponseStatus(BAD_REQUEST) @ResponseBody - public ResponseEntity<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, WebRequest request) { + public ResponseEntity<ErrorInfo> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) { BindingErrorsResponse errors = new BindingErrorsResponse(); BindingResult bindingResult = ex.getBindingResult(); - HttpHeaders headers = new HttpHeaders(); if (bindingResult.hasErrors()) { errors.addAllErrors(bindingResult); - headers.add("errors", errors.toJSON()); + return ResponseEntity.badRequest().body(new ErrorInfo("MethodArgumentNotValidException", "Validation failed")); } - return new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST); + return ResponseEntity.badRequest().build(); } - private class ErrorInfo { - public final String className; - public final String exMessage; - - public ErrorInfo(Exception ex) { - this.className = ex.getClass().getName(); - this.exMessage = ex.getLocalizedMessage(); - } - } }