Fix validation errors handling in websocket

Make sanitize raises correct BadRequest exceptions in api utils.

Change-Id: I58e77b6f89a3a511f71c2c6074f7be9a4fbdd7c5
Closes-Bug: #1479687
This commit is contained in:
Thomas Herve 2015-07-30 11:39:03 +02:00
parent a091c66df7
commit 96e87a1ea9
4 changed files with 56 additions and 10 deletions

View File

@ -382,9 +382,14 @@ class Endpoints(object):
('body', '*', None),
)
messages = api_utils.sanitize(messages,
_message_post_spec,
doctype=list)
try:
messages = api_utils.sanitize(messages,
_message_post_spec,
doctype=list)
except api_errors.BadRequest as ex:
LOG.debug(ex)
headers = {'status': 400}
return api_utils.error_response(req, ex, headers)
try:
client_uuid = api_utils.get_client_uuid(req)

View File

@ -26,15 +26,15 @@ class ExceptionBase(Exception):
class BadRequest(ExceptionBase):
"""Raised when an invalid request is received."""
msg_format = u'Bad request. {error} {description}'
msg_format = u'Bad request. {description}'
def __init__(self, error, description):
def __init__(self, description):
"""Initializes the error with contextual information.
:param description: Error description
"""
super(BadRequest, self).__init__(error=error, description=description)
super(BadRequest, self).__init__(description=description)
class DocumentTypeNotSupported(ExceptionBase):

View File

@ -54,7 +54,7 @@ def sanitize(document, spec=None, doctype=dict):
if not isinstance(document, dict):
raise api_errors.DocumentTypeNotSupported()
return document if spec is None else filter(document, spec)
return document if spec is None else filter_fields(document, spec)
if doctype is list:
if not isinstance(document, list):
@ -63,12 +63,12 @@ def sanitize(document, spec=None, doctype=dict):
if spec is None:
return document
return [filter(obj, spec) for obj in document]
return [filter_fields(obj, spec) for obj in document]
raise TypeError(_(u'Doctype must be either a JSONObject or JSONArray'))
def filter(document, spec):
def filter_fields(document, spec):
"""Validates and retrieves typed fields from a single document.
Sanitizes a dict-like document by checking it against a
@ -143,7 +143,7 @@ def get_client_uuid(req):
return uuid.UUID(req._headers.get('Client-ID'))
except ValueError:
description = _(u'Malformed hexadecimal UUID.')
raise api_errors.BadRequest(_(u'Wrong UUID value'), description)
raise api_errors.BadRequest(description)
def get_headers(req):

View File

@ -278,6 +278,47 @@ class MessagesBaseTest(base.V1_1Base):
resp = self._post_messages(queue_name)
self.assertEqual(resp['headers']['status'], 201)
def test_post_invalid_ttl(self):
sample_messages = [
{'body': {'key': 'value'}, 'ttl': '200'},
]
action = "message_post"
body = {"queue_name": "kitkat",
"messages": sample_messages}
send_mock = mock.patch.object(self.protocol, 'sendMessage')
self.addCleanup(send_mock.stop)
send_mock = send_mock.start()
req = test_utils.create_request(action, body, self.headers)
self.protocol.onMessage(req, False)
resp = json.loads(send_mock.call_args[0][0])
self.assertEqual(400, resp['headers']['status'])
self.assertEqual(
'Bad request. The value of the "ttl" field must be a int.',
resp['body']['exception'])
def test_post_no_body(self):
sample_messages = [
{'ttl': 200},
]
action = "message_post"
body = {"queue_name": "kitkat",
"messages": sample_messages}
send_mock = mock.patch.object(self.protocol, 'sendMessage')
self.addCleanup(send_mock.stop)
send_mock = send_mock.start()
req = test_utils.create_request(action, body, self.headers)
self.protocol.onMessage(req, False)
resp = json.loads(send_mock.call_args[0][0])
self.assertEqual(400, resp['headers']['status'])
self.assertEqual(
'Bad request. Missing "body" field.', resp['body']['exception'])
def test_get_from_missing_queue(self):
action = "message_list"
body = {"queue_name": "anothernonexistent"}