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.pbm.ampl.exception;

import java.util.ArrayList;
import java.util.Collection;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;

import org.springframework.core.Ordered;

/**
* This class is runs the Spring Boot application.
*
* @author Ian Meinert
* @since 1.0
*/
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {

/**
* The application logger.
*/
static final Logger LOGGER = LoggerFactory.getLogger(RestExceptionHandler.class);

/**
* This exception is thrown when argument annotated with @ Valid failed validation.
*/
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) {
Collection<String> errors = new ArrayList<String>();
for (FieldError error : ex.getBindingResult().getFieldErrors()) {
errors.add(error.getField() + ": " + error.getDefaultMessage());
}
for (ObjectError error : ex.getBindingResult().getGlobalErrors()) {
errors.add(error.getObjectName() + ": " + error.getDefaultMessage());
}

ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.getReasonPhrase(), errors);

LOGGER.warn(apiError.toString());

return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}

/**
* This exception is thrown when no handler is found.
*/
@Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) {
String error = "No handler found for " + ex.getHttpMethod() + " " + ex.getRequestURL();

ApiError apiError = new ApiError(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.getReasonPhrase(), error);

LOGGER.warn(apiError.toString());

return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}

/**
* This exception is thrown when the HttpRequest method is not supported.
*/
@Override
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
StringBuilder builder = new StringBuilder();
builder.append(ex.getMethod());
builder.append(" method is not supported for this request. Supported methods are ");
ex.getSupportedHttpMethods().forEach(t -> builder.append(t + " "));

ApiError apiError = new ApiError(HttpStatus.METHOD_NOT_ALLOWED, HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase(),
builder.toString());

LOGGER.warn(apiError.toString());

return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}

/**
* This exception is thrown when the HttpMedia type is not supported.
*/
@Override
protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) {
StringBuilder builder = new StringBuilder();
builder.append(ex.getContentType());
builder.append(" media type is not supported. Supported media types are ");
ex.getSupportedMediaTypes().forEach(t -> builder.append(t + ", "));

ApiError apiError = new ApiError(HttpStatus.UNSUPPORTED_MEDIA_TYPE, HttpStatus.UNSUPPORTED_MEDIA_TYPE.getReasonPhrase(),
builder.substring(0, builder.length() - 2));

LOGGER.warn(apiError.toString());

return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}

/**
* This exception reports the result of constraint violations.
*
* @param ex the {@link ConstraintViolationException}
* @param request the WebRequest
* @return ResponseEntity
*/
@ExceptionHandler({ ConstraintViolationException.class })
public ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException ex, WebRequest request) {
Collection<String> errors = new ArrayList<String>();

for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
errors.add(
violation.getRootBeanClass().getName() + " " + violation.getPropertyPath() + ": " + violation.getMessage());
}

ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.getReasonPhrase(), errors);

LOGGER.error(apiError.toString());

return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}

/**
* This exception reports the result of constraint violations.
*
* @param ex the {@link ConstraintViolationException}
* @param request the WebRequest
* @return ResponseEntity
*/
@ExceptionHandler({ InvalidRequestException.class })
public ResponseEntity<Object> handleRequestException(InvalidRequestException ex, WebRequest request) {

ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.getReasonPhrase(), ex.getMessage());

LOGGER.warn(apiError.toString());

return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}

/**
* This exception is thrown when method argument is not the expected type.
*
* @param ex the {@link ResourceNotFoundException}
* @param request the WebRequest
* @return ResponseEntity
*/
@ExceptionHandler({ ResourceNotFoundException.class })
protected ResponseEntity<Object> handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {

ApiError apiError = new ApiError(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.getReasonPhrase(), ex.getMessage());

LOGGER.warn(apiError.toString());

return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}

/**
* This exception is thrown when method argument is not the expected type.
*
* @param ex the {@link MethodArgumentTypeMismatchException}
* @param request the WebRequest
* @return ResponseEntity
*/
@ExceptionHandler({ MethodArgumentTypeMismatchException.class })
public ResponseEntity<Object> handleMethodArgumentTypeMismatch(MethodArgumentTypeMismatchException ex, WebRequest request) {
String error = ex.getName() + " should be of type " + ex.getRequiredType().getName();

ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.getReasonPhrase(), error);

LOGGER.warn(apiError.toString());

return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}

/**
* The default handler.
*
* @param ex the {@link Exception}
* @param request the {@link WebRequest}
* @return {@link ResponseEntity}
*/
@ExceptionHandler({ Exception.class })
public ResponseEntity<Object> handleAll(Exception ex, WebRequest request) {
ApiError apiError = new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(),
"An error occurred. Please contact an administrator.");

LOGGER.warn(apiError.toString(), ex);

return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}
}