package io.spring.api.exception; import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @RestControllerAdvice public class CustomizeExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler({InvalidRequestException.class}) public ResponseEntity handleInvalidRequest(RuntimeException e, WebRequest request) { InvalidRequestException ire = (InvalidRequestException) e; List errorResources = ire.getErrors().getFieldErrors().stream() .map( fieldError -> new FieldErrorResource( fieldError.getObjectName(), fieldError.getField(), fieldError.getCode(), fieldError.getDefaultMessage())) .collect(Collectors.toList()); ErrorResource error = new ErrorResource(errorResources); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); return handleExceptionInternal(e, error, headers, UNPROCESSABLE_ENTITY, request); } @ExceptionHandler(InvalidAuthenticationException.class) public ResponseEntity handleInvalidAuthentication( InvalidAuthenticationException e, WebRequest request) { return ResponseEntity.status(UNPROCESSABLE_ENTITY) .body( new HashMap() { { put("message", e.getMessage()); } }); } @Override protected ResponseEntity handleMethodArgumentNotValid( MethodArgumentNotValidException e, HttpHeaders headers, HttpStatus status, WebRequest request) { List errorResources = e.getBindingResult().getFieldErrors().stream() .map( fieldError -> new FieldErrorResource( fieldError.getObjectName(), fieldError.getField(), fieldError.getCode(), fieldError.getDefaultMessage())) .collect(Collectors.toList()); return ResponseEntity.status(UNPROCESSABLE_ENTITY).body(new ErrorResource(errorResources)); } @ExceptionHandler({ConstraintViolationException.class}) @ResponseStatus(UNPROCESSABLE_ENTITY) @ResponseBody public ErrorResource handleConstraintViolation( ConstraintViolationException ex, WebRequest request) { List errors = new ArrayList<>(); for (ConstraintViolation violation : ex.getConstraintViolations()) { FieldErrorResource fieldErrorResource = new FieldErrorResource( violation.getRootBeanClass().getName(), getParam(violation.getPropertyPath().toString()), violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName(), violation.getMessage()); errors.add(fieldErrorResource); } return new ErrorResource(errors); } private String getParam(String s) { String[] splits = s.split("\\."); if (splits.length == 1) { return s; } else { return String.join(".", Arrays.copyOfRange(splits, 2, splits.length)); } } }