package org.ihtsdo.otf.refset.error; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.ihtsdo.otf.refset.common.Meta; import org.ihtsdo.otf.refset.common.Result; import org.ihtsdo.otf.refset.exception.EntityAlreadyExistException; import org.ihtsdo.otf.refset.exception.EntityNotFoundException; import org.ihtsdo.otf.refset.exception.ExportServiceException; import org.ihtsdo.otf.refset.exception.InvalidServiceException; import org.ihtsdo.otf.refset.exception.RefsetServiceException; import org.ihtsdo.otf.refset.exception.ValidationException; import org.ihtsdo.otf.snomed.exception.ConceptServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.security.access.AccessDeniedException; import org.springframework.util.StringUtils; import org.springframework.validation.FieldError; import org.springframework.web.bind.ServletRequestBindingException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; @ControllerAdvice public class RefsetExceptionResolver { private static final Logger LOGGER = LoggerFactory.getLogger(RefsetExceptionResolver.class); //TODO need to formalize private static final String ERROR_CODE_SERVER = "55011"; private static final String ERROR_CODE_GEN = "44011"; final Result<Map<String, Object>> response = new Result<Map<String, Object>>(); @ResponseStatus(value = HttpStatus.NOT_FOUND) @ExceptionHandler(EntityNotFoundException.class) @ResponseBody Result<Map<String, Object>> handleEntityNotFoundException(EntityNotFoundException e) { LOGGER.error("Exception details \n", e); ErrorInfo errorInfo = new ErrorInfo(e.getMessage(), Integer.toString(org.apache.commons.httpclient.HttpStatus.SC_NOT_FOUND)); Meta m = new Meta(); m.setStatus(HttpStatus.NOT_FOUND); m.setMessage(e.getMessage()); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } @ResponseStatus(value = HttpStatus.FOUND) @ExceptionHandler(EntityAlreadyExistException.class) @ResponseBody Result<Map<String, Object>> handleEntityAlreadyExistException(EntityAlreadyExistException e) { LOGGER.error("Exception details \n", e); ErrorInfo errorInfo = new ErrorInfo(e.getMessage(), "302"); Meta m = new Meta(); m.setStatus(HttpStatus.FOUND); m.setMessage(e.getMessage()); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } @ResponseStatus(value = HttpStatus.NOT_FOUND) @ExceptionHandler(InvalidServiceException.class) @ResponseBody Result<Map<String, Object>> handleInvalidService(InvalidServiceException e) { LOGGER.error("Exception details \n", e); ErrorInfo errorInfo = new ErrorInfo(e.getMessage(), Integer.toString(org.apache.commons.httpclient.HttpStatus.SC_NOT_FOUND)); Meta m = new Meta(); m.setStatus(HttpStatus.NOT_FOUND); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } @ResponseStatus(HttpStatus.OK) @ExceptionHandler(ExportServiceException.class) @ResponseBody Result<Map<String, Object>> handleExportException(ExportServiceException e) { LOGGER.error("Exception details \n", e); ErrorInfo errorInfo = new ErrorInfo("Error occurred during export. Try after sometime", ERROR_CODE_SERVER); Meta m = new Meta(); m.setStatus(HttpStatus.OK); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } @ResponseStatus(HttpStatus.OK) @ExceptionHandler @ResponseBody Result<Map<String, Object>> handleGlobalException(Exception e) { LOGGER.error("Exception details \n", e); ErrorInfo errorInfo = new ErrorInfo("An unknown error occurred in service call, try after sometime", ERROR_CODE_GEN); Meta m = new Meta(); m.setStatus(HttpStatus.OK); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } @ResponseStatus(HttpStatus.OK) @ExceptionHandler(RefsetServiceException.class) @ResponseBody Result<Map<String, Object>> handleRefsetServiceException(RefsetServiceException e) { LOGGER.error("Exception details \n", e); ErrorInfo errorInfo = new ErrorInfo("An unknown error occurred in service call, try after sometime", ERROR_CODE_SERVER); Meta m = new Meta(); m.setStatus(HttpStatus.OK); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } @ResponseStatus(HttpStatus.OK) @ExceptionHandler(ConceptServiceException.class) @ResponseBody Result<Map<String, Object>> handleConceptServiceException(ConceptServiceException e) { LOGGER.error("Exception details \n", e); ErrorInfo errorInfo = new ErrorInfo("An unknown error occurred in service call, try after sometime", ERROR_CODE_SERVER); Meta m = new Meta(); m.setStatus(HttpStatus.OK); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } @ResponseStatus(HttpStatus.UNAUTHORIZED) @ExceptionHandler(AccessDeniedException.class) @ResponseBody Result<Map<String, Object>> handleAccessDeniedException(AccessDeniedException e) { LOGGER.error("Exception details \n", e); String message = StringUtils.isEmpty(e.getMessage()) ? "Unauthorized access, please check provided credentials in service call" : e.getMessage(); ErrorInfo errorInfo = new ErrorInfo(message, Integer.toString(org.apache.commons.httpclient.HttpStatus.SC_UNAUTHORIZED)); Meta m = new Meta(); m.setStatus(HttpStatus.UNAUTHORIZED); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(ValidationException.class) @ResponseBody Result<Map<String, Object>> handleValidationException(ValidationException e) { LOGGER.error("Exception details \n", e); String message = StringUtils.isEmpty(e.getMessage()) ? "Request does not conform to expected input. Please see error details and try again" : e.getMessage(); Map<Object,List<FieldError>> failures = e.getFailures(); Set<Object> keys = failures.keySet(); Map<Object,List<ErrorInfo>> vFailures = new HashMap<Object, List<ErrorInfo>>(); for (Object key : keys) { List<FieldError> fErrors = failures.get(key); List<ErrorInfo> errors = new ArrayList<ErrorInfo>(); for (FieldError fieldError : fErrors) { ErrorInfo info = new ErrorInfo(fieldError.getCode(), fieldError.getField()); errors.add(info); } vFailures.put(key, errors); } ErrorInfo errorInfo = new ErrorInfo(message, Integer.toString(org.apache.commons.httpclient.HttpStatus.SC_BAD_REQUEST), vFailures ); Meta m = new Meta(); m.setStatus(HttpStatus.BAD_REQUEST); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(HttpMessageNotReadableException.class) @ResponseBody Result<Map<String, Object>> handleValidationException(HttpMessageNotReadableException e) { LOGGER.error("Exception details \n", e); String message = StringUtils.isEmpty(e.getMessage()) ? "Request does not conform to expected input. Please see error details and try again" : e.getMessage(); ErrorInfo errorInfo = new ErrorInfo(message, Integer.toString(org.apache.commons.httpclient.HttpStatus.SC_BAD_REQUEST)); Meta m = new Meta(); m.setStatus(HttpStatus.BAD_REQUEST); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(ServletRequestBindingException.class) @ResponseBody Result<Map<String, Object>> handleRequesBindingException(ServletRequestBindingException e) { LOGGER.error("Exception details \n", e); String message = StringUtils.isEmpty(e.getMessage()) ? "Request does not conform to expected input. Please see error details and try again" : e.getMessage(); ErrorInfo errorInfo = new ErrorInfo(message, Integer.toString(org.apache.commons.httpclient.HttpStatus.SC_BAD_REQUEST)); Meta m = new Meta(); m.setStatus(HttpStatus.BAD_REQUEST); m.setErrorInfo(errorInfo); response.setMeta(m); return response; } }