ReST API: Refactor error handler as a context manager
The format parse method was making nasty use of magic strings that were intended only as error messages to the user in order to switch between two different behaviours that are each exercised in exactly one place. Since it is basically just a method for consistent error handling, refactor it as a context manager. Change-Id: Ibc33cc5186601a2669652484b2360c8123d263cd
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
Stack endpoint for Heat v1 ReST API.
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
from oslo_log import log as logging
|
||||
import six
|
||||
from six.moves.urllib import parse
|
||||
@@ -69,17 +70,10 @@ class InstantiationData(object):
|
||||
self.data[rpc_api.PARAM_EXISTING] = True
|
||||
|
||||
@staticmethod
|
||||
def format_parse(data, data_type):
|
||||
"""
|
||||
Parse the supplied data as JSON or YAML, raising the appropriate
|
||||
exception if it is in the wrong format.
|
||||
"""
|
||||
|
||||
@contextlib.contextmanager
|
||||
def parse_error_check(data_type):
|
||||
try:
|
||||
if data_type == 'Environment':
|
||||
return environment_format.parse(data)
|
||||
else:
|
||||
return template_format.parse(data)
|
||||
yield
|
||||
except ValueError as parse_ex:
|
||||
mdict = {'type': data_type, 'error': six.text_type(parse_ex)}
|
||||
msg = _("%(type)s not in valid format: %(error)s") % mdict
|
||||
@@ -121,7 +115,8 @@ class InstantiationData(object):
|
||||
else:
|
||||
raise exc.HTTPBadRequest(_("No template specified"))
|
||||
|
||||
return self.format_parse(template_data, 'Template')
|
||||
with self.parse_error_check('Template'):
|
||||
return template_format.parse(template_data)
|
||||
|
||||
def environment(self):
|
||||
"""
|
||||
@@ -135,8 +130,8 @@ class InstantiationData(object):
|
||||
if isinstance(env_data, dict):
|
||||
env = env_data
|
||||
else:
|
||||
env = self.format_parse(env_data,
|
||||
'Environment')
|
||||
with self.parse_error_check('Environment'):
|
||||
env = environment_format.parse(env_data)
|
||||
|
||||
environment_format.default_for_missing(env)
|
||||
parameters = self.data.get(self.PARAM_USER_PARAMS, {})
|
||||
|
||||
@@ -34,6 +34,7 @@ import heat.api.openstack.v1.stacks as stacks
|
||||
from heat.common import exception as heat_exc
|
||||
from heat.common import identifier
|
||||
from heat.common import policy
|
||||
from heat.common import template_format
|
||||
from heat.common import urlfetch
|
||||
from heat.common import wsgi
|
||||
from heat.rpc import api as rpc_api
|
||||
@@ -64,22 +65,18 @@ def to_remote_error(error):
|
||||
|
||||
class InstantiationDataTest(common.HeatTestCase):
|
||||
|
||||
def test_format_parse(self):
|
||||
data = {"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"key1": ["val1[0]", "val1[1]"],
|
||||
"key2": "val2"}
|
||||
json_repr = ('{"AWSTemplateFormatVersion" : "2010-09-09",'
|
||||
'"key1": [ "val1[0]", "val1[1]" ], '
|
||||
'"key2": "val2" }')
|
||||
parsed = stacks.InstantiationData.format_parse(json_repr, 'foo')
|
||||
self.assertEqual(data, parsed)
|
||||
def test_parse_error_success(self):
|
||||
with stacks.InstantiationData.parse_error_check('Garbage'):
|
||||
pass
|
||||
|
||||
def test_format_parse_invalid(self):
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
stacks.InstantiationData.format_parse,
|
||||
'!@#$%^¬ json', 'Garbage')
|
||||
def test_parse_error(self):
|
||||
def generate_error():
|
||||
with stacks.InstantiationData.parse_error_check('Garbage'):
|
||||
raise ValueError
|
||||
|
||||
def test_format_parse_invalid_message(self):
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, generate_error)
|
||||
|
||||
def test_parse_error_message(self):
|
||||
# make sure the parser error gets through to the caller.
|
||||
bad_temp = '''
|
||||
heat_template_version: '2013-05-23'
|
||||
@@ -89,10 +86,13 @@ parameters:
|
||||
description: bla
|
||||
'''
|
||||
|
||||
parse_ex = self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
stacks.InstantiationData.format_parse,
|
||||
bad_temp, 'foo')
|
||||
def generate_error():
|
||||
with stacks.InstantiationData.parse_error_check('foo'):
|
||||
template_format.parse(bad_temp)
|
||||
|
||||
parse_ex = self.assertRaises(webob.exc.HTTPBadRequest, generate_error)
|
||||
self.assertIn('line 4, column 3', six.text_type(parse_ex))
|
||||
self.assertIn('foo', six.text_type(parse_ex))
|
||||
|
||||
def test_stack_name(self):
|
||||
body = {'stack_name': 'wibble'}
|
||||
|
||||
Reference in New Issue
Block a user