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

View File

@ -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

View File

@ -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)

View File

@ -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"])

View File

@ -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)