-
-
Notifications
You must be signed in to change notification settings - Fork 248
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
Unable to handle "Connection reset by peer" ? #455
Comments
just had a look at util.py and I can see the following: CONNECTION_ERRORS = (requests.exceptions.ChunkedEncodingError, requests.exceptions.ConnectionError,
requests.exceptions.Timeout, socket.timeout)
if not PY2:
# Python2 does not have ConnectionResetError
CONNECTION_ERRORS += (ConnectionResetError,) try:
while True:
back_off_until = protocol.credentials.back_off_until
if back_off_until:
sleep_secs = (back_off_until - datetime.datetime.now()).total_seconds()
# The back off value may have expired within the last few milliseconds
if sleep_secs > 0:
log.warning('Server requested back off until %s. Sleeping %s seconds', back_off_until, sleep_secs)
time.sleep(sleep_secs)
log.debug('Session %s thread %s: retry %s timeout %s POST\'ing to %s after %ss wait', session.session_id,
thread_id, retry, protocol.TIMEOUT, url, wait)
d_start = time_func()
try:
r = session.post(url=url, headers=headers, data=data, allow_redirects=False, timeout=protocol.TIMEOUT)
except CONNECTION_ERRORS as e:
log.debug('Session %s thread %s: connection error POST\'ing to %s', session.session_id, thread_id, url)
r = DummyResponse(url=url, headers={'TimeoutException': e}, request_headers=headers)
except Exception:
# Always create a dummy response for logging purposes, before re-raising
r = DummyResponse(url=url, headers={}, request_headers=headers)
raise
finally:
log_vals = dict(
retry=retry,
wait=wait,
timeout=protocol.TIMEOUT,
session_id=session.session_id,
thread_id=thread_id,
auth=session.auth,
url=str(r.url),
adapter=session.get_adapter(url),
allow_redirects=allow_redirects,
response_time=time_func() - d_start,
status_code=r.status_code,
request_headers=r.request.headers,
response_headers=r.headers,
xml_request=data,
xml_response=r.content,
)
log.debug(log_msg, log_vals)
if _may_retry_on_error(r, protocol, wait):
log.info("Session %s thread %s: Connection error on URL %s (code %s). Cool down %s secs",
session.session_id, thread_id, r.url, r.status_code, wait)
time.sleep(wait) # Increase delay for every retry
retry += 1
wait *= 2
session = protocol.renew_session(session)
continue def _may_retry_on_error(r, protocol, wait):
# The genericerrorpage.htm/internalerror.asp is ridiculous behaviour for random outages. Redirect to
# '/internalsite/internalerror.asp' or '/internalsite/initparams.aspx' is caused by e.g. TLS certificate
# f*ckups on the Exchange server.
if (r.status_code == 401) \
or (r.headers.get('connection') == 'close') \
or (r.status_code == 302 and r.headers.get('location', '').lower() ==
'/ews/genericerrorpage.htm?aspxerrorpath=/ews/exchange.asmx') \
or (r.status_code == 503):
if r.status_code not in (301, 302, 401, 503):
# Don't retry if we didn't get a status code that we can hope to recover from
return False
if protocol.credentials.fail_fast:
return False
if wait > protocol.credentials.max_wait:
# We lost patience. Session is cleaned up in outer loop
raise RateLimitError('URL %s: Max timeout reached' % r.url)
return True
return False So it looks like there is logic to handle errors and retry however I don't see how to handle "ConnectionResetError, 104" is it a matter of making changes to the _may_retry_on_error function to include requests.exceptions.ConnectionError ? Cheers, C |
The ServiceAccount class will activate the retry logic. Use this class in place of the |
Wow - staring me in the face 😄
Thankyou and thankyou for a fantastic library |
+100 on the fantastic library. I had the same issue. Came here and now it is resolved. Appreciate the code and explanation posted here |
I am sorry I didn't understand what to use instead of the Credentials class, can you write an example please. |
The Instead, use a retry policy: https://github.com/ecederstrand/exchangelib#fault-tolerance |
Hi,
Is it possible to handle connection reset by peer by adding in some retry logic ?
after a few hours of pulling down emails - its annoying that the script dies, only for me to start it up again and have to start from scratch :(
Im assuming a try, except block is needed to handle this condition ?
Cheers,
C
The text was updated successfully, but these errors were encountered: