From 683a0448710b55c6e7d986a6cdb28d23795df12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Wr=C3=B3bel?= Date: Mon, 3 Oct 2016 12:41:38 +0200 Subject: [PATCH 1/2] Test exceptions' serialization with `pickle`. --- tests/unit/test_exceptions.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/unit/test_exceptions.py b/tests/unit/test_exceptions.py index 355e8478ef..b182c78d9e 100644 --- a/tests/unit/test_exceptions.py +++ b/tests/unit/test_exceptions.py @@ -11,6 +11,7 @@ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. +import pickle from nose.tools import assert_equals from botocore import exceptions @@ -47,6 +48,26 @@ def test_retry_info_added_when_present(): raise AssertionError("retry information not inject into error " "message: %s" % error_msg) +def test_waiter_error_is_pickleable(): + exception = exceptions.WaiterError('object_available', 'timeout', {}) + exception2 = pickle.loads(pickle.dumps(exception)) + + assert_equals(exception.__repr__(), exception2.__repr__()) + assert_equals(str(exception), str(exception2)) + assert_equals(type(exception), type(exception2)) + assert_equals(exception.kwargs, exception2.kwargs) + +def test_client_error_is_pickleable(): + response = {'Error': {}} + + exception = exceptions.ClientError(response, 'blackhole') + exception2 = pickle.loads(pickle.dumps(exception)) + + assert_equals(exception.__repr__(), exception2.__repr__()) + assert_equals(str(exception), str(exception2)) + assert_equals(type(exception), type(exception2)) + assert_equals(exception.response, exception2.response) + assert_equals(exception.operation_name, exception2.operation_name) def test_retry_info_not_added_if_retry_attempts_not_present(): response = { From 270bdb0c8002384d2eab622ccac951589e62ed2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Wr=C3=B3bel?= Date: Mon, 3 Oct 2016 12:42:33 +0200 Subject: [PATCH 2/2] Fix exceptions' serialization with `pickle`. --- botocore/exceptions.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/botocore/exceptions.py b/botocore/exceptions.py index f0fd172505..89d89561dd 100644 --- a/botocore/exceptions.py +++ b/botocore/exceptions.py @@ -24,10 +24,12 @@ class BotoCoreError(Exception): fmt = 'An unspecified error occurred' def __init__(self, **kwargs): - msg = self.fmt.format(**kwargs) - Exception.__init__(self, msg) + self.message = self.fmt.format(**kwargs) self.kwargs = kwargs + def __str__(self): + return self.message + class DataNotFoundError(BotoCoreError): """ @@ -350,13 +352,12 @@ class ClientError(Exception): def __init__(self, error_response, operation_name): retry_info = self._get_retry_info(error_response) - msg = self.MSG_TEMPLATE.format( + self.message = self.MSG_TEMPLATE.format( error_code=error_response['Error'].get('Code', 'Unknown'), error_message=error_response['Error'].get('Message', 'Unknown'), operation_name=operation_name, retry_info=retry_info, ) - super(ClientError, self).__init__(msg) self.response = error_response self.operation_name = operation_name @@ -370,6 +371,9 @@ def _get_retry_info(self, response): metadata['RetryAttempts']) return retry_info + def __str__(self): + return self.message + class UnsupportedTLSVersionWarning(Warning): """Warn when an openssl version that uses TLS 1.2 is required"""