1 package org.petify.image.exception; 2 3 import org.springframework.http.HttpHeaders; 4 import org.springframework.http.HttpStatus; 5 import org.springframework.http.HttpStatusCode; 6 import org.springframework.http.ProblemDetail; 7 import org.springframework.http.ResponseEntity; 8 import org.springframework.security.access.AccessDeniedException; 9 import org.springframework.web.bind.MethodArgumentNotValidException; 10 import org.springframework.web.bind.annotation.ExceptionHandler; 11 import org.springframework.web.bind.annotation.RestControllerAdvice; 12 import org.springframework.web.context.request.WebRequest; 13 import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; 14 15 import java.time.Instant; 16 import java.util.HashMap; 17 import java.util.Map; 18 19 @RestControllerAdvice 20 public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { 21 22 @ExceptionHandler(AccessDeniedException.class) 23 ProblemDetail handleAccessDeniedException(WebRequest request) { 24 ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.FORBIDDEN); 25 problemDetail.setTitle("Access Denied"); 26 problemDetail.setDetail(request.getDescription(false)); 27 problemDetail.setProperty("timestamp", Instant.now()); 28 return problemDetail; 29 } 30 31 @ExceptionHandler(Exception.class) 32 ProblemDetail handleGenericException(Exception ex) { 33 ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.INTERNAL_SERVER_ERROR); 34 problemDetail.setTitle("Internal Server Error"); 35 problemDetail.setDetail("An unexpected error occurred: " + ex.getMessage()); 36 problemDetail.setProperty("timestamp", Instant.now()); 37 return problemDetail; 38 } 39 40 @Override 41 protected ResponseEntity<Object> handleMethodArgumentNotValid( 42 MethodArgumentNotValidException ex, 43 HttpHeaders headers, 44 HttpStatusCode status, 45 WebRequest request) { 46 47 ProblemDetail problemDetail = ProblemDetail.forStatus(status); 48 problemDetail.setTitle("Validation Failed"); 49 50 Map<String, String> errors = new HashMap<>(); 51 ex.getBindingResult().getFieldErrors().forEach(error -> 52 errors.put(error.getField(), error.getDefaultMessage()) 53 ); 54 55 problemDetail.setProperty("errors", errors); 56 57 return new ResponseEntity<>(problemDetail, headers, status); 58 } 59 60 @ExceptionHandler(ImageNotFoundException.class) 61 ProblemDetail handleImageNotFound(ImageNotFoundException ex) { 62 ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.NOT_FOUND); 63 problemDetail.setTitle("Image Not Found"); 64 problemDetail.setDetail(ex.getMessage()); 65 problemDetail.setProperty("timestamp", Instant.now()); 66 return problemDetail; 67 } 68 69 @ExceptionHandler(MaxImagesReachedException.class) 70 ProblemDetail handleMaxImagesReached(MaxImagesReachedException ex) { 71 ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.CONFLICT); 72 problemDetail.setTitle("Max Images Reached"); 73 problemDetail.setDetail(ex.getMessage()); 74 problemDetail.setProperty("timestamp", Instant.now()); 75 return problemDetail; 76 } 77 }