Code used to raise an unhandled exception if the resulting error is not an XML
(ElementTree ParseError when creating S3Error object). In certain cases (e.g.
5xx errors), this also disrupted the retry flow.
Easily reproducible when running a simple 's3cmd ls' while s3cfg has an http
proxy set up, and the proxy denies all requests - returns a non-XML 403 error.
* Also extracted a method for the XML Error parsing to clean the code a little.
... | ... |
@@ -46,14 +46,13 @@ class S3Error (S3Exception): |
46 | 46 |
for header in response["headers"]: |
47 | 47 |
debug("HttpHeader: %s: %s" % (header, response["headers"][header])) |
48 | 48 |
if response.has_key("data") and response["data"]: |
49 |
- tree = getTreeFromXml(response["data"]) |
|
50 |
- error_node = tree |
|
51 |
- if not error_node.tag == "Error": |
|
52 |
- error_node = tree.find(".//Error") |
|
53 |
- for child in error_node.getchildren(): |
|
54 |
- if child.text != "": |
|
55 |
- debug("ErrorXML: " + child.tag + ": " + repr(child.text)) |
|
56 |
- self.info[child.tag] = child.text |
|
49 |
+ try: |
|
50 |
+ tree = getTreeFromXml(response["data"]) |
|
51 |
+ except ET.ParseError: |
|
52 |
+ debug("Not an XML response") |
|
53 |
+ else: |
|
54 |
+ self.info.update(self.parse_error_xml(tree)) |
|
55 |
+ |
|
57 | 56 |
self.code = self.info["Code"] |
58 | 57 |
self.message = self.info["Message"] |
59 | 58 |
self.resource = self.info["Resource"] |
... | ... |
@@ -65,6 +64,20 @@ class S3Error (S3Exception): |
65 | 65 |
retval += (u": %s" % self.info["Message"]) |
66 | 66 |
return retval |
67 | 67 |
|
68 |
+ @staticmethod |
|
69 |
+ def parse_error_xml(tree): |
|
70 |
+ info = {} |
|
71 |
+ error_node = tree |
|
72 |
+ if not error_node.tag == "Error": |
|
73 |
+ error_node = tree.find(".//Error") |
|
74 |
+ for child in error_node.getchildren(): |
|
75 |
+ if child.text != "": |
|
76 |
+ debug("ErrorXML: " + child.tag + ": " + repr(child.text)) |
|
77 |
+ info[child.tag] = child.text |
|
78 |
+ |
|
79 |
+ return info |
|
80 |
+ |
|
81 |
+ |
|
68 | 82 |
class CloudFrontError(S3Error): |
69 | 83 |
pass |
70 | 84 |
|