package de.rwth.idsg.bikeman.web.rest.exception; import lombok.extern.slf4j.Slf4j; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.TypeMismatchException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.client.RestClientException; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; import java.util.Locale; /** * Created by sgokay on 14.07.14. */ @ControllerAdvice(basePackages = "de.rwth.idsg.bikeman.web.rest") @Slf4j public class GeneralExceptionHandler { @Autowired private MessageSource messageSource; @ExceptionHandler(Exception.class) public ResponseEntity<ErrorMessage> processException(Exception e) { log.error("Exception happened", e); HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; ErrorMessage msg = new ErrorMessage( status.value(), status.getReasonPhrase(), e.getMessage() ); return new ResponseEntity<>(msg, status); } @ExceptionHandler(DataAccessException.class) public ResponseEntity<ErrorMessage> processDataAccessException(DataAccessException e) { log.error("Exception happened", e); // Fallback to most general message, when we have no cause String errorMsg = e.getMessage(); // Inception level 1 if (e.getCause() != null) { errorMsg = e.getCause().getMessage(); // Inception level 2 if (e.getCause().getCause() != null) { errorMsg = e.getCause().getCause().getMessage(); } } HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; ErrorMessage msg = new ErrorMessage( status.value(), status.getReasonPhrase(), errorMsg ); return new ResponseEntity<>(msg, status); } /** * Catches the controller path errors of the Rest API. * * Example: If a controller declares an integer in the path, but frontend sends anything but an integer. */ @ExceptionHandler(TypeMismatchException.class) public ResponseEntity<ErrorMessage> processTypeException(TypeMismatchException e) { log.error("Exception happened", e); HttpStatus status = HttpStatus.UNPROCESSABLE_ENTITY; ErrorMessage msg = new ErrorMessage( status.value(), status.getReasonPhrase(), e.getMessage() ); return new ResponseEntity<>(msg, status); } /** * Catches the Hibernate validation errors and * responds with an error message in appropriate language. */ @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<ErrorMessage> processValidationException(MethodArgumentNotValidException e) { log.error("Exception happened", e); Locale currentLocale = LocaleContextHolder.getLocale(); List<FieldError> errors = e.getBindingResult().getFieldErrors(); List<String> errorMessages = new ArrayList<>(); for (FieldError fieldError : errors) { String localizedError = messageSource.getMessage(fieldError, currentLocale); errorMessages.add(localizedError); } HttpStatus status = HttpStatus.BAD_REQUEST; ErrorMessage msg = new ErrorMessage( status.value(), status.getReasonPhrase(), "Validation failed for the submitted form" ); msg.setFieldErrors(errorMessages); return new ResponseEntity<>(msg, status); } }