def _handle_error_response(self, response: httpclient.HTTPResponse, num_of_retries: int, retries_remaining: List[int]): try: parsed_body = ET.fromstring(response.body) if EbxmlErrorEnvelope.is_ebxml_error(parsed_body): _, parsed_response = ebxml_handler.handle_ebxml_error( response.code, response.headers, response.body) logger.warning( '0007', 'Received ebxml errors from Spine. {HTTPStatus} {Errors}', { 'HTTPStatus': response.code, 'Errors': parsed_response }) elif SOAPFault.is_soap_fault(parsed_body): _, parsed_response, soap_fault_codes = handle_soap_error( response.code, response.headers, response.body) logger.warning( '0008', 'Received soap errors from Spine. {HTTPStatus} {Errors}', { 'HTTPStatus': response.code, 'Errors': parsed_response }) if SOAPFault.is_soap_fault_retriable(soap_fault_codes): logger.warning( "0015", "A retriable error was encountered {error} {retries_remaining} " "{max_retries}", { "error": parsed_response, "retries_remaining": retries_remaining[0], "max_retries": num_of_retries }) if retries_remaining[0] <= 0: # exceeded the number of retries so return the SOAP error response logger.error( "0016", "A request has exceeded the maximum number of retries, {max_retries} " "retries", {"max_retries": num_of_retries}) else: raise _NeedToRetryException() else: logger.warning('0017', "Received an unexpected response from Spine", {'HTTPStatus': response.code}) parsed_response = "Didn't get expected response from Spine" except ET.ParseError as pe: logger.warning('0010', 'Unable to parse response from Spine. {Exception}', {'Exception': repr(pe)}) parsed_response = 'Unable to handle response returned from Spine' return 500, parsed_response, None
def test_soap_error_codes_are_retriable_or_not(self): errors_and_expected = [ ("a retriable failure to process message error code 200", [200], True), ("a retriable routing failure error code 206", [206], True), ("a retriable failure storing memo error code 208", [208], True), ("a NON retriable error code 300", [300], False), ("a NON retriable set of error codes 300, 207", [300, 207], False), ("a mix of retriable and NON retriable error codes 300, 206", [300, 206], False), ("a mix of retriable and NON retriable error codes 206, 300", [206, 300], False), ("a set of retriable error codes 208, 206", [208, 206], True) ] for description, error, expected_result in errors_and_expected: with self.subTest(description): result = SOAPFault.is_soap_fault_retriable(error) self.assertEqual(result, expected_result)