Search in sources :

Example 1 with ServiceErrorList

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;
}
Also used : Status(javax.ws.rs.core.Response.Status) ServiceError(com.ibm.watson.service.base.model.ServiceError) AuthenticationException(ca.uhn.fhir.rest.server.exceptions.AuthenticationException) ArrayList(java.util.ArrayList) JsonParseException(com.fasterxml.jackson.core.JsonParseException) BaseServerResponseException(ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException) ServiceErrorList(com.ibm.cohort.engine.api.service.model.ServiceErrorList) ErrorSource(com.ibm.cohort.engine.api.service.model.ServiceErrorList.ErrorSource) FhirClientConnectionException(ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException) MismatchedInputException(com.fasterxml.jackson.databind.exc.MismatchedInputException) ResourceNotFoundException(ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException) CqlException(org.opencds.cqf.cql.engine.exception.CqlException)

Example 2 with 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"));
}
Also used : Response(javax.ws.rs.core.Response) IMultipartBody(com.ibm.websphere.jaxrs20.multipart.IMultipartBody) ByteArrayInputStream(java.io.ByteArrayInputStream) IAttachment(com.ibm.websphere.jaxrs20.multipart.IAttachment) ServiceErrorList(com.ibm.cohort.engine.api.service.model.ServiceErrorList) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Example 3 with ServiceErrorList

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);
}
Also used : Response(javax.ws.rs.core.Response) FhirClientConnectionException(ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException) ServiceErrorList(com.ibm.cohort.engine.api.service.model.ServiceErrorList) Test(org.junit.Test)

Example 4 with ServiceErrorList

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);
}
Also used : Response(javax.ws.rs.core.Response) FhirClientConnectionException(ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException) ServiceErrorList(com.ibm.cohort.engine.api.service.model.ServiceErrorList) ConnectException(java.net.ConnectException) Test(org.junit.Test)

Example 5 with ServiceErrorList

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);
}
Also used : Response(javax.ws.rs.core.Response) FhirClientConnectionException(ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException) ServiceErrorList(com.ibm.cohort.engine.api.service.model.ServiceErrorList) Test(org.junit.Test)

Aggregations

ServiceErrorList (com.ibm.cohort.engine.api.service.model.ServiceErrorList)17 Response (javax.ws.rs.core.Response)15 Test (org.junit.Test)15 FhirClientConnectionException (ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException)7 ResourceNotFoundException (ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException)4 AuthenticationException (ca.uhn.fhir.rest.server.exceptions.AuthenticationException)2 ConnectException (java.net.ConnectException)2 OperationOutcome (org.hl7.fhir.r4.model.OperationOutcome)2 CqlException (org.opencds.cqf.cql.engine.exception.CqlException)2 BaseServerResponseException (ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException)1 JsonParseException (com.fasterxml.jackson.core.JsonParseException)1 MismatchedInputException (com.fasterxml.jackson.databind.exc.MismatchedInputException)1 ErrorSource (com.ibm.cohort.engine.api.service.model.ServiceErrorList.ErrorSource)1 ServiceError (com.ibm.watson.service.base.model.ServiceError)1 IAttachment (com.ibm.websphere.jaxrs20.multipart.IAttachment)1 IMultipartBody (com.ibm.websphere.jaxrs20.multipart.IMultipartBody)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ArrayList (java.util.ArrayList)1 ResponseBuilder (javax.ws.rs.core.Response.ResponseBuilder)1 Status (javax.ws.rs.core.Response.Status)1