Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding a new method to retry jsonDecode errors #3

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions tap_sendgrid/syncs.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ def get_using_paged(self, stream, add_params=None, url_key=None):
page = 1
page_size = 1000
endpoint = stream.endpoint.format(url_key) if url_key else stream.endpoint
page_attempts = 0

while True:
params = {
Expand All @@ -179,11 +180,21 @@ def get_using_paged(self, stream, add_params=None, url_key=None):
endpoint,
self.ctx.config,
params=params)
yield r
if not end_of_records_check(r):
page += 1
else:
break
try:
yield r.json()
if not end_of_records_check(r):
page_attempts = 0
page += 1
else:
break
except JSONDecodeError:
page_attempts += 1
if page_attempts > 3:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-- here it should be > or <? you want to continue trying to decode r until page_attempts reach 3 right?
-- also, I am not sure if it will catch JSONDecodeError if you don't put "except JSONDecodeError:" right after yield r.json()? my feeling is it might throw an error when you are on line 184 without even reaching line 190, but I am not sure.
-- on line 60 I think we don't need .json() anymore because we are giving it .json() already.
-- if there is an error with decoding and we have to retry decoding, we will be refetching the whole page again, is that the goal? The problem is with .json() not working properly or with page being broken?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • changed it to <, it should be decoding until 3 attempts
  • not sure if there is a problem with the decode statement but refactored just to be safe
  • You are right about line 60 so I changed that
  • The problem is with .json not working properly, sometimes there is an issue where it doesnt decode properly so I just want to try retrying that line again so we don't have to restart the whole tap

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good! The only concern I have is that when we go from one retry to next if we are getting JSONDecoder error, I think we are repeating everything from line 174, i.e. getting the page again, no? If that's the case, then it's better to wrap .json() method into the for loop, i.e. something like this:

while page_attempts < 3:
     try:
          yield r.json()
     except JSONDecodeError:
                page_attempts += 1
                if page_attempts =< 3:
                    continue
                else:
                    logger.error(f'Status code throwing error {r.status_code}')
                    logger.error(f'Content for invalid request:\n{r.content}')
                    raise ValueError('Error parsing file...')
    break
```

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So jsondecodeError seems like its a transient issue so I can't tell if the issue was with the api call or with the .json() method. I want to make the whole api call again just incase that the response we got back from the api is what is corrupted that this is a true retry. It's hard to replicate and test this so that is why I want to retry the whole block to make sure a retry fixes it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense! then all good :)

continue
else:
logger.error(f'Status code throwing error {r.status_code}')
logger.error(f'Content for invalid request:\n{r.content}')
raise ValueError('Error parsing file...')

def get_using_offset(self, stream, start, end, url_key=None):
offset = 0
Expand Down