Makes error msg more helpful

In the case that designate api returns an error response which
does not have an 'message' entry, CLI will prints out nothing helpful
for users. The patch grabs info from response to try to provide a helpful msg.

Fixed axfr resource too.

Change-Id: I810426b6d4f731cc5ead4372083abf6515c05dc3
This commit is contained in:
James Li 2015-08-21 04:00:10 +00:00 committed by Graham Hayes
parent f2192badc1
commit 87a48c7725
4 changed files with 78 additions and 7 deletions

@ -37,14 +37,28 @@ class NoUniqueMatch(Base):
class RemoteError(Base): class RemoteError(Base):
def __init__(self, message=None, code=None, type=None, errors=None, def __init__(self, message=None, code=None, type=None, errors=None,
request_id=None): request_id=None):
super(RemoteError, self).__init__(message) err_message = self._get_error_message(message, type, errors)
self.message = err_message
self.message = message
self.code = code self.code = code
self.type = type self.type = type
self.errors = errors self.errors = errors
self.request_id = request_id 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): class Unknown(RemoteError):
pass pass

@ -0,0 +1,56 @@
# Copyright 2015 Rackspace Inc.
#
# Author: James Li <james.li@rackspace.com>
#
# 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)

@ -129,7 +129,7 @@ class TestZones(v2.APIV2TestCase, v2.CrudMixin):
def test_task_axfr(self): def test_task_axfr(self):
ref = self.new_ref() 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.stub_url("POST", parts=parts)
self.client.zones.axfr(ref["id"]) self.client.zones.axfr(ref["id"])

@ -28,12 +28,13 @@ class ZoneController(client.Controller):
} }
if type_ == "PRIMARY": if type_ == "PRIMARY":
data["email"] = email if email:
data["email"] = email
if ttl is not None: if ttl is not None:
data["ttl"] = ttl data["ttl"] = ttl
elif type_ == "SECONDARY": elif type_ == "SECONDARY" and masters:
data["masters"] = masters data["masters"] = masters
if description is not None: if description is not None:
@ -75,7 +76,7 @@ class ZoneController(client.Controller):
def axfr(self, zone): def axfr(self, zone):
zone = v2_utils.resolve_by_name(self.list, 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) self.client.session.post(url)