429 is not used by aws but by other s3 compatible servers to ask to slow
down requests
| ... | ... |
@@ -41,7 +41,7 @@ except ImportError: |
| 41 | 41 |
## s3cmd exceptions |
| 42 | 42 |
|
| 43 | 43 |
class S3Exception(Exception): |
| 44 |
- def __init__(self, message = ""): |
|
| 44 |
+ def __init__(self, message=""): |
|
| 45 | 45 |
self.message = S3.Utils.unicodise(message) |
| 46 | 46 |
|
| 47 | 47 |
def __str__(self): |
| ... | ... |
@@ -58,6 +58,7 @@ class S3Exception(Exception): |
| 58 | 58 |
## (Base)Exception.message has been deprecated in Python 2.6 |
| 59 | 59 |
def _get_message(self): |
| 60 | 60 |
return self._message |
| 61 |
+ |
|
| 61 | 62 |
def _set_message(self, message): |
| 62 | 63 |
self._message = message |
| 63 | 64 |
message = property(_get_message, _set_message) |
| ... | ... |
@@ -68,9 +69,9 @@ class S3Error (S3Exception): |
| 68 | 68 |
self.status = response["status"] |
| 69 | 69 |
self.reason = response["reason"] |
| 70 | 70 |
self.info = {
|
| 71 |
- "Code" : "", |
|
| 72 |
- "Message" : "", |
|
| 73 |
- "Resource" : "" |
|
| 71 |
+ "Code": "", |
|
| 72 |
+ "Message": "", |
|
| 73 |
+ "Resource": "" |
|
| 74 | 74 |
} |
| 75 | 75 |
debug("S3Error: %s (%s)" % (self.status, self.reason))
|
| 76 | 76 |
if "headers" in response: |
| ... | ... |
@@ -114,7 +115,7 @@ class S3Error (S3Exception): |
| 114 | 114 |
return ExitCodes.EX_PRECONDITION |
| 115 | 115 |
elif self.status == 500: |
| 116 | 116 |
return ExitCodes.EX_SOFTWARE |
| 117 |
- elif self.status == 503: |
|
| 117 |
+ elif self.status in [429, 503]: |
|
| 118 | 118 |
return ExitCodes.EX_SERVICE |
| 119 | 119 |
else: |
| 120 | 120 |
return ExitCodes.EX_SOFTWARE |
| ... | ... |
@@ -1422,7 +1422,7 @@ class S3(object): |
| 1422 | 1422 |
if response["status"] == 405: # Method Not Allowed. Don't retry. |
| 1423 | 1423 |
raise S3Error(response) |
| 1424 | 1424 |
|
| 1425 |
- if response["status"] >= 500: |
|
| 1425 |
+ if response["status"] >= 500 or response["status"] == 429: |
|
| 1426 | 1426 |
e = S3Error(response) |
| 1427 | 1427 |
|
| 1428 | 1428 |
if response["status"] == 501: |
| ... | ... |
@@ -1663,11 +1663,16 @@ class S3(object): |
| 1663 | 1663 |
if response["status"] < 200 or response["status"] > 299: |
| 1664 | 1664 |
try_retry = False |
| 1665 | 1665 |
if response["status"] >= 500: |
| 1666 |
- ## AWS internal error - retry |
|
| 1666 |
+ # AWS internal error - retry |
|
| 1667 | 1667 |
try_retry = True |
| 1668 | 1668 |
if response["status"] == 503: |
| 1669 | 1669 |
## SlowDown error |
| 1670 | 1670 |
throttle = throttle and throttle * 5 or 0.01 |
| 1671 |
+ elif response["status"] == 429: |
|
| 1672 |
+ # Not an AWS error, but s3 compatible server possible error: |
|
| 1673 |
+ # TooManyRequests/Busy/slowdown |
|
| 1674 |
+ try_retry = True |
|
| 1675 |
+ throttle = throttle and throttle * 5 or 0.01 |
|
| 1671 | 1676 |
elif response["status"] >= 400: |
| 1672 | 1677 |
err = S3Error(response) |
| 1673 | 1678 |
## Retriable client error? |