From ef6a7e7b4ccedb61815c2bf2ccb1980cad648304 Mon Sep 17 00:00:00 2001 From: Lin Yang <lin.a.yang@intel.com> Date: Sun, 6 Sep 2015 15:34:19 +0800 Subject: [PATCH] Convert api internal TypeError to HTTPBadRequest Previously, when created environment without environment name provided, it return meaningless HTTP 500 with internal TypeError exception traceback. So add ResourceExceptionHandler to convert these exceptions generated by API implementation methods to webob exception. Change-Id: I221a6e0d36afb04b4d0c12f6a9c0d1f1da6f9bdb Closes-Bug: #1491788 --- murano/common/wsgi.py | 32 ++++++++++++++++++- murano/tests/unit/api/v1/test_environments.py | 11 +++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/murano/common/wsgi.py b/murano/common/wsgi.py index 2350ca9d..8997c5be 100644 --- a/murano/common/wsgi.py +++ b/murano/common/wsgi.py @@ -339,6 +339,34 @@ class Request(webob.Request): return content_type +class ResourceExceptionHandler(object): + """Context manager to handle Resource exceptions. + + Used when processing exceptions generated by API implementation + methods. Converts most exceptions to webob exceptions, with the + appropriate logging. + """ + + def __enter__(self): + return None + + def __exit__(self, ex_type, ex_value, ex_traceback): + if not ex_value: + return True + + # TODO(lin.a.yang): current only handle TypeError here, we should + # process other kind of internal exceptions generated by API and + # convert to webob exceptions. + if isinstance(ex_value, TypeError): + exc_info = (ex_type, ex_value, ex_traceback) + LOG.error(_("Exception handling resource: {0}").format(ex_value), + exc_info=exc_info) + raise webob.exc.HTTPBadRequest() + + # We didn't handle this kind of exception + return False + + class Resource(object): """WSGI app that handles (de)serialization and controller dispatch. @@ -381,7 +409,9 @@ class Resource(object): msg = _("Malformed request body") return webob.exc.HTTPBadRequest(explanation=msg) - action_result = self.execute_action(action, request, **action_args) + with ResourceExceptionHandler(): + action_result = self.execute_action(action, request, **action_args) + try: return self.serialize_response(action, action_result, accept) # return unserializable result (typically a webob exc) diff --git a/murano/tests/unit/api/v1/test_environments.py b/murano/tests/unit/api/v1/test_environments.py index b3816afd..1216b9d4 100644 --- a/murano/tests/unit/api/v1/test_environments.py +++ b/murano/tests/unit/api/v1/test_environments.py @@ -191,6 +191,17 @@ class TestEnvironmentApi(tb.ControllerTest, tb.MuranoApiTestCase): self.assertIn('Environment name should be 255 characters maximum', result_msg) + def test_create_environment_with_empty_body(self): + """Check that empty request body results in an HTTPBadResquest.""" + body = '' + req = self._post('/environments', body) + result = req.get_response(self.api) + self.assertEqual(400, result.status_code) + result_msg = result.text.replace('\n', '') + self.assertIn('The server could not comply with the request since it ' + 'is either malformed or otherwise incorrect.', + result_msg) + def test_missing_environment(self): """Check that a missing environment results in an HTTPNotFound.