jenkins-job-builder/jenkins_jobs/errors.py
Darragh Bailey cae9e63fc4 Find module for exceptions raised from gen_xml
Include ability to retrieve the necessary module information when
exceptions are raised from within the gen_xml function for those modules
that implement using this function directly instead of calling dispatch.
Also to ensure that the exception itself won't raise an exception due to
not being able to detect the correct calling module, ensure a default
value noting it was not able to detect the module is always set first.

Provide a fallback when the code can explicitly specify the module as
the source component of the exception for cases where it may not be
possible to autodetect.

Change-Id: I3f72fe5f05a5e1f40a089e1f828dd295501bd9c7
2015-07-14 15:42:42 +01:00

70 lines
2.1 KiB
Python

"""Exception classes for jenkins_jobs errors"""
import inspect
def is_sequence(arg):
return (not hasattr(arg, "strip") and
(hasattr(arg, "__getitem__") or
hasattr(arg, "__iter__")))
class JenkinsJobsException(Exception):
pass
class ModuleError(JenkinsJobsException):
def get_module_name(self):
frame = inspect.currentframe()
co_name = frame.f_code.co_name
module_name = '<unresolved>'
while frame and co_name != 'run':
# XML generation called via dispatch
if co_name == 'dispatch':
data = frame.f_locals
module_name = "%s.%s" % (data['component_type'], data['name'])
break
# XML generation done directly by class using gen_xml
if co_name == 'gen_xml':
data = frame.f_locals['data']
module_name = next(iter(data.keys()))
break
frame = frame.f_back
co_name = frame.f_code.co_name
return module_name
class InvalidAttributeError(ModuleError):
def __init__(self, attribute_name, value, valid_values=None):
message = "'{0}' is an invalid value for attribute {1}.{2}".format(
value, self.get_module_name(), attribute_name)
if is_sequence(valid_values):
message += "\nValid values include: {0}".format(
', '.join("'{0}'".format(value)
for value in valid_values))
super(InvalidAttributeError, self).__init__(message)
class MissingAttributeError(ModuleError):
def __init__(self, missing_attribute, module_name=None):
module = module_name or self.get_module_name()
if is_sequence(missing_attribute):
message = "One of {0} must be present in '{1}'".format(
', '.join("'{0}'".format(value)
for value in missing_attribute), module)
else:
message = "Missing {0} from an instance of '{1}'".format(
missing_attribute, module)
super(MissingAttributeError, self).__init__(message)
class YAMLFormatError(JenkinsJobsException):
pass