use of com.ibm.cohort.engine.api.service.model.ServiceErrorList in project quality-measure-and-cohort-service by Alvearie.
the class CohortServiceExceptionMapper method toServiceErrorList.
public ServiceErrorList toServiceErrorList(Throwable ex) {
List<ServiceError> errorsList = new ArrayList<>();
// The IBM Cloud API Handbook mandates that REST errors be returned using
// an error container model class (ServiceErrorList) which in turn contains
// a list of error objects (ServiceError) which contains specific error fields
// serviceErrorList contains the status request (ie 400, 500 etc.) for our service
// and the status code for underlying services is captured in the serviceError objects
// within the list
ServiceErrorList serviceErrorList = new ServiceErrorList().errors(errorsList);
ServiceError se;
String description = "";
String reason = "";
int serviceErrorCode = 500;
int serviceErrorListCode = 500;
ErrorSource errorSource;
try {
if (ex instanceof FhirClientConnectionException) {
FhirClientConnectionException fcce = (FhirClientConnectionException) ex;
serviceErrorCode = fcce.getStatusCode();
// if something more specific is not returned
if (serviceErrorCode == 0) {
serviceErrorCode = Status.BAD_REQUEST.getStatusCode();
}
serviceErrorListCode = serviceErrorCode;
Status status = Status.fromStatusCode(serviceErrorCode);
reason = fcce.getLocalizedMessage();
if (reason == null || reason.trim().isEmpty()) {
reason = status.getReasonPhrase();
}
description = "Reason: FhirClientConnectionException";
errorSource = ErrorSource.COHORT_SERVICE;
} else // The 401 error code information is captured in the ServiceError object
if (ex instanceof AuthenticationException) {
AuthenticationException ae = (AuthenticationException) ex;
serviceErrorListCode = Status.BAD_REQUEST.getStatusCode();
serviceErrorCode = ae.getStatusCode();
description = "Could not authenticate with FHIR server.";
errorSource = ErrorSource.FHIR_SERVER;
} else if (ex instanceof ResourceNotFoundException) {
ResourceNotFoundException rnfe = (ResourceNotFoundException) ex;
serviceErrorListCode = Status.BAD_REQUEST.getStatusCode();
serviceErrorCode = rnfe.getStatusCode();
reason = "FHIR Resource Not Found: " + rnfe.getLocalizedMessage();
description = rnfe.getResponseBody();
errorSource = ErrorSource.FHIR_SERVER;
} else // library ids don't resolve properly
if (ex instanceof IllegalArgumentException || ex instanceof UnsupportedOperationException) {
serviceErrorCode = Status.BAD_REQUEST.getStatusCode();
serviceErrorListCode = serviceErrorCode;
errorSource = ErrorSource.COHORT_SERVICE;
} else // will get thrown by the CQL engine generally due to language-related issues
if (ex instanceof CqlException) {
serviceErrorCode = Status.BAD_REQUEST.getStatusCode();
serviceErrorListCode = serviceErrorCode;
errorSource = ErrorSource.COHORT_SERVICE;
} else // parsing errors.
if (ex instanceof MismatchedInputException) {
serviceErrorCode = Status.BAD_REQUEST.getStatusCode();
serviceErrorListCode = serviceErrorCode;
errorSource = ErrorSource.COHORT_SERVICE;
} else if (ex instanceof JsonParseException) {
serviceErrorCode = Status.BAD_REQUEST.getStatusCode();
serviceErrorListCode = serviceErrorCode;
description = "Invalid JSON input";
errorSource = ErrorSource.COHORT_SERVICE;
} else // will get thrown by HAPI FHIR when a requested resource is not found in the target FHIR server
if (ex instanceof BaseServerResponseException) {
serviceErrorCode = ((BaseServerResponseException) ex).getStatusCode();
serviceErrorListCode = serviceErrorCode;
BaseServerResponseException sre = (BaseServerResponseException) ex;
reason = "Exception while communicating with FHIR";
errorSource = ErrorSource.FHIR_SERVER;
if (sre.getResponseBody() != null) {
description = sre.getResponseBody();
} else {
// Some errors do not have a response body
description = sre.getLocalizedMessage();
}
} else // catch everything else and return a 500
{
serviceErrorCode = Status.INTERNAL_SERVER_ERROR.getStatusCode();
serviceErrorListCode = serviceErrorCode;
description = ex.getMessage();
errorSource = ErrorSource.COHORT_SERVICE;
}
if (reason.isEmpty()) {
reason = ex.getLocalizedMessage();
}
se = new ServiceError(serviceErrorCode, reason);
se.setDescription(description);
errorsList.add(se);
// loop through the exception chain logging the cause of each one
// since these can contain valuable information about the root problems
createServiceErrorsForExceptions(ex, serviceErrorCode, errorsList);
serviceErrorList = serviceErrorList.statusCode(serviceErrorListCode).errorSource(errorSource);
logger.error("HTTP Status: " + serviceErrorList.getStatusCode(), ex);
} catch (Throwable nestedEx) {
// This should not really occur unless there is a bug in this code.
// Build a 500 ServiceError with some detail
se = new ServiceError(Status.INTERNAL_SERVER_ERROR.getStatusCode(), nestedEx.getLocalizedMessage());
se.setDescription("Reason: Uncaught nested exception");
logger.error("HTTP Status: " + se.getCode() + ", Nested Exception", nestedEx);
logger.error("Original Exception", ex);
serviceErrorList = serviceErrorList.statusCode(se.getCode()).errorSource(ErrorSource.COHORT_SERVICE);
errorsList.add(se);
}
return serviceErrorList;
}
use of com.ibm.cohort.engine.api.service.model.ServiceErrorList in project quality-measure-and-cohort-service by Alvearie.
the class CohortEngineRestHandlerTest method testEvaluateMeasureInvalidMeasureJSON.
@PrepareForTest({ Response.class, TenantManager.class, ServiceBaseUtility.class })
@Test
public void testEvaluateMeasureInvalidMeasureJSON() throws Exception {
prepMocks();
PowerMockito.mockStatic(ServiceBaseUtility.class);
PowerMockito.when(ServiceBaseUtility.apiSetup(VERSION, logger, MethodNames.EVALUATE_MEASURE.getName())).thenReturn(null);
mockResponseClasses();
// Create the metadata part of the request
String json = "{ \"something\": \"unexpected\" }";
ByteArrayInputStream jsonIs = new ByteArrayInputStream(json.getBytes());
IAttachment rootPart = mockAttachment(jsonIs);
// Create the ZIP part of the request
IAttachment measurePart = mockAttachment(TestHelper.emptyZip());
// Assemble them together into a reasonable facsimile of the real request
IMultipartBody body = mock(IMultipartBody.class);
when(body.getAttachment(CohortEngineRestHandler.REQUEST_DATA_PART)).thenReturn(rootPart);
when(body.getAttachment(CohortEngineRestHandler.MEASURE_PART)).thenReturn(measurePart);
Response loadResponse = restHandler.evaluateMeasure(mockRequestContext, VERSION, body);
assertNotNull(loadResponse);
PowerMockito.verifyStatic(Response.class);
Response.status(400);
ArgumentCaptor<ServiceErrorList> errorBody = ArgumentCaptor.forClass(ServiceErrorList.class);
Mockito.verify(mockResponseBuilder).entity(errorBody.capture());
assertTrue(errorBody.getValue().getErrors().get(0).getMessage().contains("Unrecognized field"));
}
use of com.ibm.cohort.engine.api.service.model.ServiceErrorList in project quality-measure-and-cohort-service by Alvearie.
the class CohortServiceExceptionMapperTest method testToResponseFhirClientConnectionExceptionUnknownHostTimedOut.
@Test
public void testToResponseFhirClientConnectionExceptionUnknownHostTimedOut() throws Exception {
Response response = exMapper.toResponse(new FhirClientConnectionException("Something bad got input").initCause(new java.net.SocketTimeoutException("timed out")));
ServiceErrorList actual = (ServiceErrorList) response.getEntity();
ServiceErrorList expected = new ServiceErrorList();
expected.setStatusCode(500);
expected.getErrors().add(newServiceError(500, "Something bad got input", "Reason: FhirClientConnectionException"));
expected.getErrors().add(newServiceError(504, "timed out", null));
expected.setErrorSource(ErrorSource.COHORT_SERVICE);
testErrorListEquality(expected, actual);
}
use of com.ibm.cohort.engine.api.service.model.ServiceErrorList in project quality-measure-and-cohort-service by Alvearie.
the class CohortServiceExceptionMapperTest method testToResponseFhirClientConnectionExceptionUnknownHttpHostConnect.
@Test
public void testToResponseFhirClientConnectionExceptionUnknownHttpHostConnect() throws Exception {
Response response = exMapper.toResponse(new FhirClientConnectionException("Something bad got input").initCause(new org.apache.http.conn.HttpHostConnectException(org.apache.http.HttpHost.create("host"), new ConnectException("cause"))));
ServiceErrorList actual = (ServiceErrorList) response.getEntity();
ServiceErrorList expected = new ServiceErrorList();
expected.setStatusCode(500);
expected.getErrors().add(newServiceError(500, "Something bad got input", "Reason: FhirClientConnectionException"));
expected.getErrors().add(newServiceError(404, "Connect to host failed: cause", null));
expected.getErrors().add(newServiceError(500, "cause", null));
expected.setErrorSource(ErrorSource.COHORT_SERVICE);
testErrorListEquality(expected, actual);
}
use of com.ibm.cohort.engine.api.service.model.ServiceErrorList in project quality-measure-and-cohort-service by Alvearie.
the class CohortServiceExceptionMapperTest method testToResponseFhirClientConnectionExceptionUnknownHostApacheTimedOut.
@Test
public void testToResponseFhirClientConnectionExceptionUnknownHostApacheTimedOut() throws Exception {
Response response = exMapper.toResponse(new FhirClientConnectionException("Something bad got input").initCause(new org.apache.http.conn.ConnectTimeoutException("timed out")));
ServiceErrorList actual = (ServiceErrorList) response.getEntity();
ServiceErrorList expected = new ServiceErrorList();
expected.setStatusCode(500);
expected.getErrors().add(newServiceError(500, "Something bad got input", "Reason: FhirClientConnectionException"));
expected.getErrors().add(newServiceError(504, "timed out", null));
expected.setErrorSource(ErrorSource.COHORT_SERVICE);
testErrorListEquality(expected, actual);
}
Aggregations