Summary Table

Categories Total Count
PII 0
URL 0
DNS 0
EKL 0
IP 0
PORT 0
VsID 0
CF 0
AI 0
VPD 0
PL 0
Other 0

File Content

package gov.va.med.ars.errorhandling;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.persistence.RollbackException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;

import org.apache.log4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindingResult;
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.bind.annotation.ResponseBody;

import gov.va.med.ars.exceptions.EntityNotFoundException;
import gov.va.med.ars.exceptions.GenericException;
import gov.va.med.ars.exceptions.ValidationException;
import gov.va.med.ars.util.ResponseMessage;

@ControllerAdvice
public class GlobalControllerExceptionHandler {

private static final Logger LOG = Logger.getLogger(GlobalControllerExceptionHandler.class);

// SECURITY ACCESS HANDLING

@ExceptionHandler(AccessDeniedException.class)
@ResponseBody
public ResponseEntity<?> handleSecurityErrors(AccessDeniedException ex) {
LOG.debug("Got access error", ex);
// fallback to server error
return new ResponseEntity<ResponseMessage>(new ResponseMessage("ERR", ex.getMessage()), HttpStatus.FORBIDDEN);
}

// GENERAL ERROR HANDLING

@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseEntity<?> handleErrors(Exception ex) {
if (ex.getCause() instanceof RollbackException
&& ex.getCause().getCause() instanceof ConstraintViolationException) {
ConstraintViolationException constraintViolationException = (ConstraintViolationException) ex.getCause()
.getCause();
return new ResponseEntity<List<ValidationMessage>>(getValidationErrorResponse(constraintViolationException),
HttpStatus.BAD_REQUEST);
} else if (ex instanceof GenericException) {
GenericException gex = (GenericException)ex;
return new ResponseEntity<ResponseMessage>(new ResponseMessage(
gex.getErrorCode(),
gex.getMessage()),
gex.getHttpStatusCode());
} else {
LOG.error("handleErrors(Exception ex) Got unusual error: (" + ex.getMessage() + " Responding with INTERNAL_SERVER_ERROR");
// Log.error("exception: ", ex); // very verbose, doesn't really help, because problem is at the other end of network.
// fallback to server error
return new ResponseEntity<ResponseMessage>(new ResponseMessage("ERR", ex.getMessage()),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}

// VALIDATION ERROR HANDLING

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResponseEntity<?> handleValidationError(MethodArgumentNotValidException ex) {
final List<ValidationMessage> validationErrors = new ArrayList<>();
ValidationMessage validationMessage = null;
BindingResult result = ex.getBindingResult();
List<FieldError> fieldErrors = result.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
validationMessage = new ValidationMessage("ERR", fieldError.getField(), fieldError.getDefaultMessage());
validationErrors.add(validationMessage);
}
return new ResponseEntity<List<ValidationMessage>>(validationErrors, HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(ValidationException.class)
@ResponseBody
public ResponseEntity<?> handleBadRequestException(ValidationException ex) {
LOG.error("Got validation errors", ex);
if (ex.getValidationMessages() == null || ex.getValidationMessages().isEmpty()) {
return new ResponseEntity<ResponseMessage>(new ResponseMessage("ERR", ex.getMessage()),
HttpStatus.BAD_REQUEST);
} else {
return new ResponseEntity<List<ValidationMessage>>(ex.getValidationMessages(), HttpStatus.BAD_REQUEST);
}
}

@ExceptionHandler(EntityNotFoundException.class)
@ResponseBody
public ResponseEntity<ResponseMessage> handleEntityNotFoundException(EntityNotFoundException ex) {
LOG.error("Could not find entity with id " + ex.getId(), ex);
return new ResponseEntity<ResponseMessage>(new ResponseMessage("ERR", ex.getMessage()), HttpStatus.NOT_FOUND);
}

private List<ValidationMessage> getValidationErrorResponse(
ConstraintViolationException constraintViolationException) {
final List<ValidationMessage> validationErrors = new ArrayList<>();
ValidationMessage validationMessage = new ValidationMessage();
LOG.error("Got validation errors", constraintViolationException);
for (ConstraintViolation<?> violationSet : constraintViolationException.getConstraintViolations()) {
List<String> propertyList = new ArrayList<>();
Iterator<Path.Node> propertyIterator = violationSet.getPropertyPath().iterator();
while (propertyIterator.hasNext()) {
propertyList.add(propertyIterator.next().getName());
}
// add violations errors in response
validationMessage.setEntity(violationSet.getRootBeanClass().getName());
validationMessage.setMessageTemplate(violationSet.getMessageTemplate().replaceAll("^[{]|[}]$", ""));
validationMessage.setPropertyList(propertyList);
validationErrors.add(validationMessage);
}
return validationErrors;
}
}