cae9e63fc4
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
70 lines
2.1 KiB
Python
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
|