aboutsummaryrefslogtreecommitdiff
path: root/discord/http.py
diff options
context:
space:
mode:
Diffstat (limited to 'discord/http.py')
-rw-r--r--discord/http.py124
1 files changed, 66 insertions, 58 deletions
diff --git a/discord/http.py b/discord/http.py
index 00e66ac2..ceb6137a 100644
--- a/discord/http.py
+++ b/discord/http.py
@@ -180,68 +180,76 @@ class HTTPClient:
if files:
for f in files:
f.reset(seek=tries)
-
- async with self.__session.request(method, url, **kwargs) as r:
- log.debug('%s %s with %s has returned %s', method, url, kwargs.get('data'), r.status)
-
- # even errors have text involved in them so this is safe to call
- data = await json_or_text(r)
-
- # check if we have rate limit header information
- remaining = r.headers.get('X-Ratelimit-Remaining')
- if remaining == '0' and r.status != 429:
- # we've depleted our current bucket
- delta = utils._parse_ratelimit_header(r, use_clock=self.use_clock)
- log.debug('A rate limit bucket has been exhausted (bucket: %s, retry: %s).', bucket, delta)
- maybe_lock.defer()
- self.loop.call_later(delta, lock.release)
-
- # the request was successful so just return the text/json
- if 300 > r.status >= 200:
- log.debug('%s %s has received %s', method, url, data)
- return data
-
- # we are being rate limited
- if r.status == 429:
- if not r.headers.get('Via'):
- # Banned by Cloudflare more than likely.
+ try:
+ async with self.__session.request(method, url, **kwargs) as r:
+ log.debug('%s %s with %s has returned %s', method, url, kwargs.get('data'), r.status)
+
+ # even errors have text involved in them so this is safe to call
+ data = await json_or_text(r)
+
+ # check if we have rate limit header information
+ remaining = r.headers.get('X-Ratelimit-Remaining')
+ if remaining == '0' and r.status != 429:
+ # we've depleted our current bucket
+ delta = utils._parse_ratelimit_header(r, use_clock=self.use_clock)
+ log.debug('A rate limit bucket has been exhausted (bucket: %s, retry: %s).', bucket, delta)
+ maybe_lock.defer()
+ self.loop.call_later(delta, lock.release)
+
+ # the request was successful so just return the text/json
+ if 300 > r.status >= 200:
+ log.debug('%s %s has received %s', method, url, data)
+ return data
+
+ # we are being rate limited
+ if r.status == 429:
+ if not r.headers.get('Via'):
+ # Banned by Cloudflare more than likely.
+ raise HTTPException(r, data)
+
+ fmt = 'We are being rate limited. Retrying in %.2f seconds. Handled under the bucket "%s"'
+
+ # sleep a bit
+ retry_after = data['retry_after'] / 1000.0
+ log.warning(fmt, retry_after, bucket)
+
+ # check if it's a global rate limit
+ is_global = data.get('global', False)
+ if is_global:
+ log.warning('Global rate limit has been hit. Retrying in %.2f seconds.', retry_after)
+ self._global_over.clear()
+
+ await asyncio.sleep(retry_after)
+ log.debug('Done sleeping for the rate limit. Retrying...')
+
+ # release the global lock now that the
+ # global rate limit has passed
+ if is_global:
+ self._global_over.set()
+ log.debug('Global rate limit is now over.')
+
+ continue
+
+ # we've received a 500 or 502, unconditional retry
+ if r.status in {500, 502}:
+ await asyncio.sleep(1 + tries * 2)
+ continue
+
+ # the usual error cases
+ if r.status == 403:
+ raise Forbidden(r, data)
+ elif r.status == 404:
+ raise NotFound(r, data)
+ else:
raise HTTPException(r, data)
- fmt = 'We are being rate limited. Retrying in %.2f seconds. Handled under the bucket "%s"'
-
- # sleep a bit
- retry_after = data['retry_after'] / 1000.0
- log.warning(fmt, retry_after, bucket)
-
- # check if it's a global rate limit
- is_global = data.get('global', False)
- if is_global:
- log.warning('Global rate limit has been hit. Retrying in %.2f seconds.', retry_after)
- self._global_over.clear()
-
- await asyncio.sleep(retry_after)
- log.debug('Done sleeping for the rate limit. Retrying...')
-
- # release the global lock now that the
- # global rate limit has passed
- if is_global:
- self._global_over.set()
- log.debug('Global rate limit is now over.')
-
- continue
-
- # we've received a 500 or 502, unconditional retry
- if r.status in {500, 502}:
- await asyncio.sleep(1 + tries * 2)
+ # This is handling exceptions from the request
+ except OSError as e:
+ # Connection reset by peer
+ if e.errno in (54, 10054):
+ # Just re-do the request
continue
- # the usual error cases
- if r.status == 403:
- raise Forbidden(r, data)
- elif r.status == 404:
- raise NotFound(r, data)
- else:
- raise HTTPException(r, data)
# We've run out of retries, raise.
raise HTTPException(r, data)