Skip to content

Loading…

Fixed up BotoServerException's use of message #1353

Closed
wants to merge 1 commit into from

2 participants

@pasc

The BotoServerException class uses getattr() to check the message variable, but this is never going to work as it inherits from StandardError which defines the same variable.

This commit changes the default behaviour to use the message variable by default instead and add support for handling the now old variable name (error_message).

This change also means that the message variable will be populated by default which people generally expect when dealing with exceptions (it's currently not).

@toastdriven toastdriven commented on the diff
boto/exception.py
@@ -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

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@toastdriven

By & large, this looks fine to me outside of that one bit of feedback.

@toastdriven toastdriven was assigned
@toastdriven

Merged in SHA: b944f4b

@toastdriven toastdriven removed their assignment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 24, 2013
  1. @pasc
Showing with 55 additions and 7 deletions.
  1. +12 −6 boto/exception.py
  2. +43 −1 tests/unit/test_exception.py
View
18 boto/exception.py
@@ -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

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
self.box_usage = None
# Attempt to parse the error response. If body isn't present,
@@ -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)
@@ -117,7 +123,7 @@ 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
@@ -125,7 +131,7 @@ def endElement(self, name, value, connection):
def _cleanupParsedProperties(self):
self.request_id = None
self.error_code = None
- self.error_message = None
+ self.message = None
self.box_usage = None
class ConsoleOutput:
View
44 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):
@@ -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')
@@ -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'
@@ -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)
Something went wrong with that request. Please try again.