diff --git a/designateclient/exceptions.py b/designateclient/exceptions.py index 9021929..df4c3f5 100644 --- a/designateclient/exceptions.py +++ b/designateclient/exceptions.py @@ -37,14 +37,28 @@ class NoUniqueMatch(Base): class RemoteError(Base): def __init__(self, message=None, code=None, type=None, errors=None, request_id=None): - super(RemoteError, self).__init__(message) - - self.message = message + err_message = self._get_error_message(message, type, errors) + self.message = err_message self.code = code self.type = type self.errors = errors self.request_id = request_id + super(RemoteError, self).__init__(err_message) + + def _get_error_message(self, _message, _type, _errors): + # Try to get a useful error msg if 'message' has nothing + if not _message: + if _errors and 'errors' in _errors: + err_msg = list() + for err in _errors['errors']: + if 'message' in err: + err_msg.append(err['message']) + _message = '. '.join(err_msg) + elif _type: + _message = str(_type) + return _message + class Unknown(RemoteError): pass diff --git a/designateclient/tests/test_exceptions.py b/designateclient/tests/test_exceptions.py new file mode 100644 index 0000000..e307e9b --- /dev/null +++ b/designateclient/tests/test_exceptions.py @@ -0,0 +1,56 @@ +# Copyright 2015 Rackspace Inc. +# +# Author: James Li +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is 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. + +from designateclient import exceptions +from designateclient.tests import base + + +class RemoteErrorTestCase(base.TestCase): + response_dict = { + 'message': None, + 'code': 500, + 'type': None, + 'errors': None, + 'request_id': 1234 + } + + def test_get_error_message(self): + expected_msg = 'something wrong' + self.response_dict['message'] = expected_msg + remote_err = exceptions.RemoteError(**self.response_dict) + self.assertEqual(expected_msg, remote_err.message) + + def test_get_error_message_with_errors(self): + expected_msg = "u'nodot.com' is not a 'domainname'" + errors = {"errors": [ + {"path": ["name"], + "message": expected_msg, + "validator": "format", + "validator_value": "domainname"} + ] + } + self.response_dict['message'] = None + self.response_dict['errors'] = errors + remote_err = exceptions.RemoteError(**self.response_dict) + self.assertEqual(expected_msg, remote_err.message) + + def test_get_error_message_with_type(self): + expected_msg = 'invalid_object' + self.response_dict['message'] = None + self.response_dict['errors'] = None + self.response_dict['type'] = expected_msg + remote_err = exceptions.RemoteError(**self.response_dict) + self.assertEqual(expected_msg, remote_err.message) diff --git a/designateclient/tests/v2/test_zones.py b/designateclient/tests/v2/test_zones.py index f7ceac8..8f7ac9d 100644 --- a/designateclient/tests/v2/test_zones.py +++ b/designateclient/tests/v2/test_zones.py @@ -129,7 +129,7 @@ class TestZones(v2.APIV2TestCase, v2.CrudMixin): def test_task_axfr(self): ref = self.new_ref() - parts = [self.RESOURCE, ref["id"], "tasks", "axfr"] + parts = [self.RESOURCE, ref["id"], "tasks", "xfr"] self.stub_url("POST", parts=parts) self.client.zones.axfr(ref["id"]) diff --git a/designateclient/v2/zones.py b/designateclient/v2/zones.py index e97df5b..a8ae74a 100644 --- a/designateclient/v2/zones.py +++ b/designateclient/v2/zones.py @@ -28,12 +28,13 @@ class ZoneController(client.Controller): } if type_ == "PRIMARY": - data["email"] = email + if email: + data["email"] = email if ttl is not None: data["ttl"] = ttl - elif type_ == "SECONDARY": + elif type_ == "SECONDARY" and masters: data["masters"] = masters if description is not None: @@ -75,7 +76,7 @@ class ZoneController(client.Controller): def axfr(self, zone): zone = v2_utils.resolve_by_name(self.list, zone) - url = '/zones/%s/tasks/axfr' % zone + url = '/zones/%s/tasks/xfr' % zone self.client.session.post(url)