Skip to content

Commit cc52587

Browse files
committed
Add retry on certain network errors
This change includes certain network level errors in the retry logic. It partially address josegonzalez#110 but I think more comprehensive fix would be useful.
1 parent 853b7c4 commit cc52587

File tree

1 file changed

+35
-3
lines changed

1 file changed

+35
-3
lines changed

github_backup/github_backup.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from urllib.request import Request
2929
from urllib.request import HTTPRedirectHandler
3030
from urllib.request import build_opener
31+
from http.client import IncompleteRead
3132

3233
try:
3334
from . import __version__
@@ -436,6 +437,21 @@ def retrieve_data_gen(args, template, query_args=None, single_request=False):
436437
r, errors = _get_response(request, auth, template)
437438

438439
status_code = int(r.getcode())
440+
# Check if we got correct data
441+
try:
442+
response = json.loads(r.read().decode('utf-8'))
443+
except IncompleteRead:
444+
log_warning("Incomplete read error detected")
445+
read_error = True
446+
except json.decoder.JSONDecodeError:
447+
log_warning("JSON decode error detected")
448+
read_error = True
449+
except TimeoutError:
450+
log_warning("Tiemout error detected")
451+
read_error = True
452+
else:
453+
read_error = False
454+
439455
# be gentle with API request limit and throttle requests if remaining requests getting low
440456
limit_remaining = int(r.headers.get('x-ratelimit-remaining', 0))
441457
if args.throttle_limit and limit_remaining <= args.throttle_limit:
@@ -446,21 +462,37 @@ def retrieve_data_gen(args, template, query_args=None, single_request=False):
446462
time.sleep(args.throttle_pause)
447463

448464
retries = 0
449-
while retries < 3 and status_code == 502:
450-
log_warning('API request returned HTTP 502: Bad Gateway. Retrying in 5 seconds')
465+
while retries < 3 and (status_code == 502 or read_error):
466+
log_warning('API request failed. Retrying in 5 seconds')
451467
retries += 1
452468
time.sleep(5)
453469
request = _construct_request(per_page, page, query_args, template, auth, as_app=args.as_app) # noqa
454470
r, errors = _get_response(request, auth, template)
455471

456472
status_code = int(r.getcode())
473+
try:
474+
response = json.loads(r.read().decode('utf-8'))
475+
read_error = False
476+
except IncompleteRead:
477+
log_warning("Incomplete read error detected")
478+
read_error = True
479+
except json.decoder.JSONDecodeError:
480+
log_warning("JSON decode error detected")
481+
read_error = True
482+
except TimeoutError:
483+
log_warning("Tiemout error detected")
484+
read_error = True
457485

458486
if status_code != 200:
459487
template = 'API request returned HTTP {0}: {1}'
460488
errors.append(template.format(status_code, r.reason))
461489
raise Exception(', '.join(errors))
462490

463-
response = json.loads(r.read().decode('utf-8'))
491+
if read_error:
492+
template = 'API request problem reading response for {0}'
493+
errors.append(template.format(request))
494+
raise Exception(', '.join(errors))
495+
464496
if len(errors) == 0:
465497
if type(response) == list:
466498
for resp in response:

0 commit comments

Comments
 (0)