Add option for detailed template error
Add option detailed_template_error for informative error during template and environment parsing. yaml.SafeLoader returns error with template snippet where error has been occurred instead of CSafeLoader. But CSafeLoader is faster. So, if user wants to get more informative error, use slower but more detailed SafeLoader for yaml loading. Change-Id: Ied0a573a00eb5f564dea0c636da1301de5de9ea7 Closes-bug: #1496361
This commit is contained in:
@@ -21,13 +21,19 @@ SECTIONS = (PARAMETER_DEFAULTS, PARAMETERS, RESOURCE_REGISTRY) = \
|
|||||||
|
|
||||||
|
|
||||||
def parse(env_str):
|
def parse(env_str):
|
||||||
'''Takes a string and returns a dict containing the parsed structure.
|
"""Takes a string and returns a dict containing the parsed structure.
|
||||||
|
|
||||||
This includes determination of whether the string is using the
|
This includes determination of whether the string is using the
|
||||||
YAML format.
|
YAML format.
|
||||||
'''
|
"""
|
||||||
try:
|
try:
|
||||||
env = yaml.load(env_str, Loader=template_format.yaml_loader)
|
env = yaml.load(env_str, Loader=template_format.yaml_loader)
|
||||||
|
except yaml.YAMLError:
|
||||||
|
# NOTE(prazumovsky): we need to return more informative error for
|
||||||
|
# user, so use SafeLoader, which return error message with template
|
||||||
|
# snippet where error has been occurred.
|
||||||
|
try:
|
||||||
|
env = yaml.load(env_str, Loader=yaml.SafeLoader)
|
||||||
except yaml.YAMLError as yea:
|
except yaml.YAMLError as yea:
|
||||||
raise ValueError(yea)
|
raise ValueError(yea)
|
||||||
else:
|
else:
|
||||||
|
@@ -40,16 +40,22 @@ yaml_loader.add_constructor(u'tag:yaml.org,2002:timestamp',
|
|||||||
|
|
||||||
|
|
||||||
def parse(tmpl_str):
|
def parse(tmpl_str):
|
||||||
'''Takes a string and returns a dict containing the parsed structure.
|
"""Takes a string and returns a dict containing the parsed structure.
|
||||||
|
|
||||||
This includes determination of whether the string is using the
|
This includes determination of whether the string is using the
|
||||||
JSON or YAML format.
|
JSON or YAML format.
|
||||||
'''
|
"""
|
||||||
if tmpl_str.startswith('{'):
|
if tmpl_str.startswith('{'):
|
||||||
tpl = json.loads(tmpl_str)
|
tpl = json.loads(tmpl_str)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
tpl = yaml.load(tmpl_str, Loader=yaml_loader)
|
tpl = yaml.load(tmpl_str, Loader=yaml_loader)
|
||||||
|
except yaml.YAMLError:
|
||||||
|
# NOTE(prazumovsky): we need to return more informative error for
|
||||||
|
# user, so use SafeLoader, which return error message with template
|
||||||
|
# snippet where error has been occurred.
|
||||||
|
try:
|
||||||
|
tpl = yaml.load(tmpl_str, Loader=yaml.SafeLoader)
|
||||||
except yaml.YAMLError as yea:
|
except yaml.YAMLError as yea:
|
||||||
raise ValueError(yea)
|
raise ValueError(yea)
|
||||||
else:
|
else:
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
from heatclient.common import environment_format
|
from heatclient.common import environment_format
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
import six
|
||||||
import testscenarios
|
import testscenarios
|
||||||
import testtools
|
import testtools
|
||||||
import yaml
|
import yaml
|
||||||
@@ -78,3 +79,14 @@ class YamlParseExceptions(testtools.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(ValueError,
|
self.assertRaises(ValueError,
|
||||||
environment_format.parse, text)
|
environment_format.parse, text)
|
||||||
|
|
||||||
|
|
||||||
|
class DetailedYAMLParseExceptions(testtools.TestCase):
|
||||||
|
|
||||||
|
def test_parse_to_value_exception(self):
|
||||||
|
yaml = """not important
|
||||||
|
but very:
|
||||||
|
- incorrect
|
||||||
|
"""
|
||||||
|
ex = self.assertRaises(ValueError, environment_format.parse, yaml)
|
||||||
|
self.assertIn('but very:\n ^', six.text_type(ex))
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
import six
|
||||||
import testscenarios
|
import testscenarios
|
||||||
import testtools
|
import testtools
|
||||||
import yaml
|
import yaml
|
||||||
@@ -48,3 +49,14 @@ Resources: {}
|
|||||||
Outputs: {}
|
Outputs: {}
|
||||||
'''
|
'''
|
||||||
self.assertRaises(ValueError, template_format.parse, yaml2)
|
self.assertRaises(ValueError, template_format.parse, yaml2)
|
||||||
|
|
||||||
|
|
||||||
|
class DetailedYAMLParseExceptions(testtools.TestCase):
|
||||||
|
|
||||||
|
def test_parse_to_value_exception(self):
|
||||||
|
yaml = """not important
|
||||||
|
but very:
|
||||||
|
- incorrect
|
||||||
|
"""
|
||||||
|
ex = self.assertRaises(ValueError, template_format.parse, yaml)
|
||||||
|
self.assertIn('but very:\n ^', six.text_type(ex))
|
||||||
|
Reference in New Issue
Block a user