Skip to content

Commit

Permalink
Add backoff handling more errors (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
butkeraites-hotglue authored Oct 24, 2024
1 parent 56676c5 commit 44c6cfd
Showing 1 changed file with 50 additions and 6 deletions.
56 changes: 50 additions & 6 deletions src/tap_intacct/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,24 @@
AuthFailure
)

from http.client import RemoteDisconnected

class PleaseTryAgainLaterError(Exception):
pass

from .const import GET_BY_DATE_FIELD, INTACCT_OBJECTS, KEY_PROPERTIES, REP_KEYS

logger = singer.get_logger()

class InvalidXmlResponse(Exception):
pass
class BadGatewayError(Exception):
pass
class OfflineServiceError(Exception):
pass
class RateLimitError(Exception):
pass

def _format_date_for_intacct(datetime: dt.datetime) -> str:
"""
Intacct expects datetimes in a 'MM/DD/YY HH:MM:SS' string format.
Expand Down Expand Up @@ -128,11 +139,22 @@ def _set_session_id(self, user_id: str, company_id: str, user_password: str):
else:
raise SageIntacctSDKError('Error: {0}'.format(response['errormessage']))

@backoff.on_exception(
backoff.expo,
(
BadGatewayError,
OfflineServiceError,
ConnectionError,
ConnectionResetError,
requests.exceptions.ConnectionError,
InternalServerError,
RateLimitError,
RemoteDisconnected,
),
max_tries=8,
factor=3,
)
@singer.utils.ratelimit(10, 1)
@backoff.on_exception(backoff.expo,
(ExpatError, PleaseTryAgainLaterError),
max_tries=5,
factor=2)
def _post_request(self, dict_body: dict, api_url: str) -> Dict:
"""
Create a HTTP post request.
Expand All @@ -148,10 +170,31 @@ def _post_request(self, dict_body: dict, api_url: str) -> Dict:
api_headers = {'content-type': 'application/xml'}
api_headers.update(self.__headers)
body = xmltodict.unparse(dict_body)
logger.info(f"request to {api_url} with body {body}")
response = requests.post(api_url, headers=api_headers, data=body)

parsed_xml = xmltodict.parse(response.text)
parsed_response = json.loads(json.dumps(parsed_xml))
logger.info(
f"request to {api_url} response {response.text}, statuscode {response.status_code}"
)
try:
parsed_xml = xmltodict.parse(response.text)
parsed_response = json.loads(json.dumps(parsed_xml))
except:
if response.status_code == 502:
raise BadGatewayError(
f"Response status code: {response.status_code}, response: {response.text}"
)
if response.status_code == 503:
raise OfflineServiceError(
f"Response status code: {response.status_code}, response: {response.text}"
)
if response.status_code == 429:
raise RateLimitError(
f"Response status code: {response.status_code}, response: {response.text}"
)
raise InvalidXmlResponse(
f"Response status code: {response.status_code}, response: {response.text}"
)

if response.status_code == 200:
if parsed_response['response']['control']['status'] == 'success':
Expand Down Expand Up @@ -453,3 +496,4 @@ def get_client(
)

return connection

0 comments on commit 44c6cfd

Please sign in to comment.