Output additional info when exceptions occur

Problems occurring deep in the code frequently need to be caught and
additional information included in the error output to help debug
issues.

Change-Id: I5aee523a3cf9e1cb7573fa6fc5a06dc3888be1ef
This commit is contained in:
Darragh Bailey 2016-04-24 03:35:00 +01:00 committed by Darragh Bailey
parent 83114faba6
commit 0f0f681069
8 changed files with 122 additions and 7 deletions

View File

@ -40,6 +40,12 @@ def deep_format(obj, paramdict, allow_empty=False):
desc = "%s parameter missing to format %s\nGiven:\n%s" % (
missing_key, obj, pformat(paramdict))
raise JenkinsJobsException(desc)
except Exception:
logging.error("Problem formatting with args:\nallow_empty:"
"%s\nobj: %s\nparamdict: %s" %
(allow_empty, obj, paramdict))
raise
elif isinstance(obj, list):
ret = type(obj)()
for item in obj:
@ -55,6 +61,11 @@ def deep_format(obj, paramdict, allow_empty=False):
desc = "%s parameter missing to format %s\nGiven:\n%s" % (
missing_key, obj, pformat(paramdict))
raise JenkinsJobsException(desc)
except Exception:
logging.error("Problem formatting with args:\nallow_empty:"
"%s\nobj: %s\nparamdict: %s" %
(allow_empty, obj, paramdict))
raise
else:
ret = obj
return ret

View File

@ -364,7 +364,12 @@ class YamlParser(object):
raise
params.update(expanded_values)
params = deep_format(params, params)
try:
params = deep_format(params, params)
except Exception:
logging.error(
"Failure formatting params '%s' with itself", params)
raise
if combination_matches(params, excludes):
logger.debug('Excluding combination %s', str(params))
continue
@ -374,9 +379,15 @@ class YamlParser(object):
params[key] = template[key]
params['template-name'] = template_name
expanded = deep_format(
template, params,
self.jjb_config.yamlparser['allow_empty_variables'])
try:
expanded = deep_format(
template, params,
self.jjb_config.yamlparser['allow_empty_variables'])
except Exception:
logging.error(
"Failure formatting template '%s', containing '%s' with "
"params '%s'", template_name, template, params)
raise
job_name = expanded.get('name')
if jobs_glob and not matches(job_name, jobs_glob):

View File

@ -163,9 +163,15 @@ class ModuleRegistry(object):
if template_data:
# Template data contains values that should be interpolated
# into the component definition
component_data = deep_format(
component_data, template_data,
self.jjb_config.yamlparser['allow_empty_variables'])
try:
component_data = deep_format(
component_data, template_data,
self.jjb_config.yamlparser['allow_empty_variables'])
except Exception:
logging.error(
"Failure formatting component ('%s') data '%s'",
name, component_data)
raise
else:
# The component is a simple string name, eg "run-tests"
name = component

View File

@ -0,0 +1,21 @@
- scm:
name: default-git-scm
scm:
- git:
url: https://github.com/openstack-infra/jenkins-job-builder.git
branches:
'{branches}'
clean: true
- project:
name: missing_params_for_component
jobs:
- 'template-requiring-component-param-{os}':
os: 'ubuntu-xenial'
- job-template:
name: 'template-requiring-component-param-{os}'
disabled: true
scm:
- default-git-scm:
branch: master

View File

@ -41,3 +41,20 @@ class TestXmlJobGeneratorExceptions(base.BaseTestCase):
e = self.assertRaises(errors.JenkinsJobsException,
xml_generator.generateXML, job_data)
self.assertIn("Unrecognized project type:", str(e))
def test_incorrect_template_params(self):
self.conf_filename = None
config = self._get_config()
yp = parser.YamlParser(config)
yp.parse(os.path.join(self.fixtures_path,
"failure_formatting_component.yaml"))
reg = registry.ModuleRegistry(config)
reg.set_parser_data(yp.data)
job_data_list, view_data_list = yp.expandYaml(reg)
xml_generator = xml_config.XmlJobGenerator(reg)
self.assertRaises(Exception, xml_generator.generateXML, job_data_list)
self.assertIn("Failure formatting component", self.logger.output)
self.assertIn("Problem formatting with args", self.logger.output)

View File

@ -0,0 +1,18 @@
- defaults:
name: global
date: 20161015
- project:
name: missing_params_for_params
# deliberately missing value for 'bdate' to trigger
# problem formatting params with default
flavor:
- trusty-{date}
- xenial-{bdate}
jobs:
- 'template-requiring-param-{os}':
os: 'ubuntu-{flavour}'
- job-template:
name: 'template-requiring-param-{os}'
disabled: true

View File

@ -0,0 +1,8 @@
- project:
name: missing_params_for_template
jobs:
- 'template-requiring-param-{os}'
- job-template:
name: 'template-requiring-param-{os}'
disabled: true

View File

@ -44,3 +44,26 @@ class TestYamlParserExceptions(base.BaseTestCase):
e = self.assertRaises(Exception, yp.expandYaml, reg)
self.assertIn("'NoneType' object is not iterable", str(e))
self.assertIn("- branch: current\n current: null", self.logger.output)
class TestYamlParserFailureFormattingExceptions(base.BaseScenariosTestCase):
fixtures_path = os.path.join(os.path.dirname(__file__), 'exceptions')
scenarios = [
('s1', {'name': 'template'}),
('s2', {'name': 'params'})
]
def test_yaml_snippet(self):
self.conf_filename = None
config = self._get_config()
yp = parser.YamlParser(config)
yp.parse(os.path.join(self.fixtures_path,
"failure_formatting_{}.yaml".format(self.name)))
reg = registry.ModuleRegistry(config)
self.assertRaises(Exception, yp.expandYaml, reg)
self.assertIn("Failure formatting {}".format(self.name),
self.logger.output)
self.assertIn("Problem formatting with args", self.logger.output)