Browse code

* S3/Exceptions.py, S3/S3.py: Some HTTP_400 exceptions are retriable.

git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/trunk@406 830e0280-6d2a-0410-9c65-932aecc39d9d

Michal Ludvig authored on 2010/05/20 18:28:44
Showing 3 changed files
... ...
@@ -1,3 +1,8 @@
1
+2010-05-20  Michal Ludvig  <mludvig@logix.net.nz>
2
+
3
+	* S3/Exceptions.py, S3/S3.py: Some HTTP_400 exceptions 
4
+	  are retriable.
5
+
1 6
 2010-03-19  Michal Ludvig  <mludvig@logix.net.nz>
2 7
 
3 8
 	* s3cmd, S3/ACL.py: Print all ACLs for a Grantee
... ...
@@ -35,7 +35,11 @@ class S3Error (S3Exception):
35 35
 	def __init__(self, response):
36 36
 		self.status = response["status"]
37 37
 		self.reason = response["reason"]
38
-		self.info = {}
38
+		self.info = {
39
+			"Code" : "",
40
+			"Message" : "",
41
+			"Resource" : ""
42
+		}
39 43
 		debug("S3Error: %s (%s)" % (self.status, self.reason))
40 44
 		if response.has_key("headers"):
41 45
 			for header in response["headers"]:
... ...
@@ -49,6 +53,9 @@ class S3Error (S3Exception):
49 49
 				if child.text != "":
50 50
 					debug("ErrorXML: " + child.tag + ": " + repr(child.text))
51 51
 					self.info[child.tag] = child.text
52
+		self.code = self.info["Code"]
53
+		self.message = self.info["Message"]
54
+		self.resource = self.info["Resource"]
52 55
 
53 56
 	def __unicode__(self):
54 57
 		retval = u"%d " % (self.status)
... ...
@@ -580,8 +580,17 @@ class S3(object):
580 580
 			response['headers']['etag'] = '' 
581 581
 
582 582
 		if response["status"] < 200 or response["status"] > 299:
583
+			try_retry = False
583 584
 			if response["status"] >= 500:
584 585
 				## AWS internal error - retry
586
+				try_retry = True
587
+			elif response["status"] >= 400:
588
+				err = S3Error(response)
589
+				## Retriable client error?
590
+				if err.code in [ 'BadDigest', 'OperationAborted', 'TokenRefreshRequired', 'RequestTimeout' ]:
591
+					try_retry = True
592
+
593
+			if try_retry:
585 594
 				if retries:
586 595
 					warning("Upload failed: %s (%s)" % (resource['uri'], S3Error(response)))
587 596
 					warning("Waiting %d sec..." % self._fail_wait(retries))
... ...
@@ -590,6 +599,7 @@ class S3(object):
590 590
 				else:
591 591
 					warning("Too many failures. Giving up on '%s'" % (file.name))
592 592
 					raise S3UploadError
593
+
593 594
 			## Non-recoverable error
594 595
 			raise S3Error(response)
595 596