Browse code

Fixes #1096 - Add http error 429 to the retryable errors

429 is not used by aws but by other s3 compatible servers to ask to slow
down requests

Florent Viard authored on 2020/05/03 07:16:56
Showing 2 changed files
... ...
@@ -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?