Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed up BotoServerException's use of message #1353

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 12 additions & 6 deletions boto/exception.py
Expand Up @@ -76,7 +76,7 @@ def __init__(self, status, reason, body=None, *args):
self.body = body or ''
self.request_id = None
self.error_code = None
self.error_message = None
self._error_message = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need updating anywhere else? If not (& if this will be using self.message in the future), is there any value in keeping it?

self.box_usage = None

# Attempt to parse the error response. If body isn't present,
Expand All @@ -90,16 +90,22 @@ def __init__(self, status, reason, body=None, *args):
# in exception. But first, save self.body in self.error_message
# because occasionally we get error messages from Eucalyptus
# that are just text strings that we want to preserve.
self.error_message = self.body
self.message = self.body
self.body = None

def __getattr__(self, name):
if name == 'message':
return self.error_message
if name == 'error_message':
return self.message
if name == 'code':
return self.error_code
raise AttributeError

def __setattr__(self, name, value):
if name == 'error_message':
self.message = value
else:
super(BotoServerError, self).__setattr__(name, value)

def __repr__(self):
return '%s: %s %s\n%s' % (self.__class__.__name__,
self.status, self.reason, self.body)
Expand All @@ -117,15 +123,15 @@ def endElement(self, name, value, connection):
elif name == 'Code':
self.error_code = value
elif name == 'Message':
self.error_message = value
self.message = value
elif name == 'BoxUsage':
self.box_usage = value
return None

def _cleanupParsedProperties(self):
self.request_id = None
self.error_code = None
self.error_message = None
self.message = None
self.box_usage = None

class ConsoleOutput:
Expand Down
44 changes: 43 additions & 1 deletion tests/unit/test_exception.py
@@ -1,6 +1,6 @@
from tests.unit import unittest

from boto.exception import BotoServerError
from boto.exception import BotoServerError, S3CreateError, JSONResponseError

class TestBotoServerError(unittest.TestCase):

Expand All @@ -23,6 +23,7 @@ def test_message_elb_xml(self):
bse = BotoServerError('400', 'Bad Request', body=xml)

self.assertEqual(bse.error_message, 'Cannot find Load Balancer webapp-balancer2')
self.assertEqual(bse.error_message, bse.message)
self.assertEqual(bse.request_id, '093f80d0-4473-11e1-9234-edce8ec08e2d')
self.assertEqual(bse.error_code, 'LoadBalancerNotFound')
self.assertEqual(bse.status, '400')
Expand All @@ -46,11 +47,51 @@ def test_message_sd_xml(self):
'Session does not have permission to perform (sdb:CreateDomain) on '
'resource (arn:aws:sdb:us-east-1:xxxxxxx:domain/test_domain). '
'Contact account owner.')
self.assertEqual(bse.error_message, bse.message)
self.assertEqual(bse.box_usage, '0.0055590278')
self.assertEqual(bse.error_code, 'AuthorizationFailure')
self.assertEqual(bse.status, '403')
self.assertEqual(bse.reason, 'Forbidden')

def test_message_storage_create_error(self):
# This test value comes from https://answers.launchpad.net/duplicity/+question/150801
xml = """<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>BucketAlreadyOwnedByYou</Code>
<Message>Your previous request to create the named bucket succeeded and you already own it.</Message>
<BucketName>cmsbk</BucketName>
<RequestId>FF8B86A32CC3FE4F</RequestId>
<HostId>6ENGL3DT9f0n7Tkv4qdKIs/uBNCMMA6QUFapw265WmodFDluP57esOOkecp55qhh</HostId>
</Error>
"""
s3ce = S3CreateError('409', 'Conflict', body=xml)

self.assertEqual(s3ce.bucket, 'cmsbk')
self.assertEqual(s3ce.error_code, 'BucketAlreadyOwnedByYou')
self.assertEqual(s3ce.status, '409')
self.assertEqual(s3ce.reason, 'Conflict')
self.assertEqual(s3ce.error_message,
'Your previous request to create the named bucket succeeded '
'and you already own it.')
self.assertEqual(s3ce.error_message, s3ce.message)
self.assertEqual(s3ce.request_id, 'FF8B86A32CC3FE4F')

def test_message_json_response_error(self):
# This test comes from https://forums.aws.amazon.com/thread.jspa?messageID=374936
body = {
'__type': 'com.amazon.coral.validate#ValidationException',
'message': 'The attempted filter operation is not supported '
'for the provided filter argument count'}

jre = JSONResponseError('400', 'Bad Request', body=body)

self.assertEqual(jre.status, '400')
self.assertEqual(jre.reason, 'Bad Request')
self.assertEqual(jre.error_message, body['message'])
self.assertEqual(jre.error_message, jre.message)
self.assertEqual(jre.code, 'ValidationException')
self.assertEqual(jre.code, jre.error_code)

def test_message_not_xml(self):
body = 'This is not XML'

Expand All @@ -62,3 +103,4 @@ def test_getters(self):

bse = BotoServerError('400', 'Bad Request', body=body)
self.assertEqual(bse.code, bse.error_code)
self.assertEqual(bse.message, bse.error_message)