forked from ungleich-public/cdist
Merge pull request #653 from darko-poljak/improve_error_reporting
Improve error reporting
This commit is contained in:
commit
0d15e1aae0
5 changed files with 68 additions and 29 deletions
|
@ -83,41 +83,72 @@ class CdistBetaRequired(cdist.Error):
|
||||||
|
|
||||||
class CdistEntityError(Error):
|
class CdistEntityError(Error):
|
||||||
"""Something went wrong while executing cdist entity"""
|
"""Something went wrong while executing cdist entity"""
|
||||||
def __init__(self, entity_name, entity_params, stderr_paths, subject=''):
|
def __init__(self, entity_name, entity_params, stdout_paths,
|
||||||
|
stderr_paths, subject=''):
|
||||||
self.entity_name = entity_name
|
self.entity_name = entity_name
|
||||||
self.entity_params = entity_params
|
self.entity_params = entity_params
|
||||||
self.stderr_paths = stderr_paths
|
self.stderr_paths = stderr_paths
|
||||||
|
self.stdout_paths = stdout_paths
|
||||||
if isinstance(subject, Error):
|
if isinstance(subject, Error):
|
||||||
self.original_error = subject
|
self.original_error = subject
|
||||||
else:
|
else:
|
||||||
self.original_error = None
|
self.original_error = None
|
||||||
self.message = str(subject)
|
self.message = str(subject)
|
||||||
|
|
||||||
@property
|
def _stdpath(self, stdpaths, header_name):
|
||||||
def stderr(self):
|
result = {}
|
||||||
output = []
|
for name, path in stdpaths:
|
||||||
for stderr_name, stderr_path in self.stderr_paths:
|
if name not in result:
|
||||||
if (os.path.exists(stderr_path) and
|
result[name] = []
|
||||||
os.path.getsize(stderr_path) > 0):
|
if os.path.exists(path) and os.path.getsize(path) > 0:
|
||||||
label_begin = '---- BEGIN ' + stderr_name + ':stderr ----'
|
output = []
|
||||||
label_end = '---- END ' + stderr_name + ':stderr ----'
|
label_begin = name + ":" + header_name
|
||||||
output.append('\n' + label_begin)
|
output.append(label_begin)
|
||||||
with open(stderr_path, 'r') as fd:
|
output.append('\n')
|
||||||
|
output.append('-' * len(label_begin))
|
||||||
|
output.append('\n')
|
||||||
|
with open(path, 'r') as fd:
|
||||||
output.append(fd.read())
|
output.append(fd.read())
|
||||||
output.append(label_end)
|
output.append('\n')
|
||||||
return '\n'.join(output)
|
result[name].append(''.join(output))
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _stderr(self):
|
||||||
|
return self._stdpath(self.stderr_paths, 'stderr')
|
||||||
|
|
||||||
|
def _stdout(self):
|
||||||
|
return self._stdpath(self.stdout_paths, 'stdout')
|
||||||
|
|
||||||
|
def _update_dict_list(self, target, source):
|
||||||
|
for x in source:
|
||||||
|
if x not in target:
|
||||||
|
target[x] = []
|
||||||
|
target[x].extend(source[x])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def std_streams(self):
|
||||||
|
std_dict = {}
|
||||||
|
self._update_dict_list(std_dict, self._stdout())
|
||||||
|
self._update_dict_list(std_dict, self._stderr())
|
||||||
|
return std_dict
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
output = []
|
output = []
|
||||||
output.append(self.message)
|
output.append(self.message)
|
||||||
header = "\nError processing " + self.entity_name
|
output.append('\n\n')
|
||||||
|
header = "Error processing " + self.entity_name
|
||||||
under_header = '=' * len(header)
|
under_header = '=' * len(header)
|
||||||
output.append(header)
|
output.append(header)
|
||||||
|
output.append('\n')
|
||||||
output.append(under_header)
|
output.append(under_header)
|
||||||
|
output.append('\n')
|
||||||
for param_name, param_value in self.entity_params:
|
for param_name, param_value in self.entity_params:
|
||||||
output.append(param_name + ': ' + str(param_value))
|
output.append(param_name + ': ' + str(param_value))
|
||||||
output.append(self.stderr + '\n')
|
output.append('\n')
|
||||||
return '\n'.join(output)
|
output.append('\n')
|
||||||
|
for x in self.std_streams:
|
||||||
|
output.append(''.join(self.std_streams[x]))
|
||||||
|
return ''.join(output)
|
||||||
|
|
||||||
|
|
||||||
class CdistObjectError(CdistEntityError):
|
class CdistObjectError(CdistEntityError):
|
||||||
|
@ -127,28 +158,38 @@ class CdistObjectError(CdistEntityError):
|
||||||
('name', cdist_object.name, ),
|
('name', cdist_object.name, ),
|
||||||
('path', cdist_object.absolute_path, ),
|
('path', cdist_object.absolute_path, ),
|
||||||
('source', " ".join(cdist_object.source), ),
|
('source', " ".join(cdist_object.source), ),
|
||||||
('type', cdist_object.cdist_type.absolute_path, ),
|
('type', os.path.realpath(cdist_object.cdist_type.absolute_path), ),
|
||||||
]
|
]
|
||||||
stderr_paths = []
|
stderr_paths = []
|
||||||
for stderr_name in os.listdir(cdist_object.stderr_path):
|
for stderr_name in os.listdir(cdist_object.stderr_path):
|
||||||
stderr_path = os.path.join(cdist_object.stderr_path,
|
stderr_path = os.path.join(cdist_object.stderr_path,
|
||||||
stderr_name)
|
stderr_name)
|
||||||
stderr_paths.append((stderr_name, stderr_path, ))
|
stderr_paths.append((stderr_name, stderr_path, ))
|
||||||
|
stdout_paths = []
|
||||||
|
for stdout_name in os.listdir(cdist_object.stdout_path):
|
||||||
|
stdout_path = os.path.join(cdist_object.stdout_path,
|
||||||
|
stdout_name)
|
||||||
|
stdout_paths.append((stdout_name, stdout_path, ))
|
||||||
super().__init__("object '{}'".format(cdist_object.name),
|
super().__init__("object '{}'".format(cdist_object.name),
|
||||||
params, stderr_paths, subject)
|
params, stdout_paths, stderr_paths, subject)
|
||||||
|
|
||||||
|
|
||||||
class InitialManifestError(CdistEntityError):
|
class InitialManifestError(CdistEntityError):
|
||||||
"""Something went wrong while executing initial manifest"""
|
"""Something went wrong while executing initial manifest"""
|
||||||
def __init__(self, initial_manifest, stderr_path, subject=''):
|
def __init__(self, initial_manifest, stdout_path, stderr_path, subject=''):
|
||||||
params = [
|
params = [
|
||||||
('path', initial_manifest, ),
|
('path', initial_manifest, ),
|
||||||
]
|
]
|
||||||
|
stdout_paths = []
|
||||||
|
stdout_paths = [
|
||||||
|
('init', stdout_path, ),
|
||||||
|
]
|
||||||
stderr_paths = []
|
stderr_paths = []
|
||||||
stderr_paths = [
|
stderr_paths = [
|
||||||
('init', stderr_path, ),
|
('init', stderr_path, ),
|
||||||
]
|
]
|
||||||
super().__init__('initial manifest', params, stderr_paths, subject)
|
super().__init__('initial manifest', params, stdout_paths,
|
||||||
|
stderr_paths, subject)
|
||||||
|
|
||||||
|
|
||||||
def file_to_list(filename):
|
def file_to_list(filename):
|
||||||
|
|
|
@ -440,9 +440,10 @@ class Config(object):
|
||||||
self.manifest.run_initial_manifest(self.local.initial_manifest)
|
self.manifest.run_initial_manifest(self.local.initial_manifest)
|
||||||
except cdist.Error as e:
|
except cdist.Error as e:
|
||||||
which = "init"
|
which = "init"
|
||||||
|
stdout_path = os.path.join(self.local.stdout_base_path, which)
|
||||||
stderr_path = os.path.join(self.local.stderr_base_path, which)
|
stderr_path = os.path.join(self.local.stderr_base_path, which)
|
||||||
raise cdist.InitialManifestError(self.local.initial_manifest,
|
raise cdist.InitialManifestError(self.local.initial_manifest,
|
||||||
stderr_path, e)
|
stdout_path, stderr_path, e)
|
||||||
self.iterate_until_finished()
|
self.iterate_until_finished()
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
self._remove_files_dirs()
|
self._remove_files_dirs()
|
||||||
|
|
|
@ -259,10 +259,8 @@ class Local(object):
|
||||||
util.log_std_fd(self.log, command, stderr, 'Local stderr')
|
util.log_std_fd(self.log, command, stderr, 'Local stderr')
|
||||||
util.log_std_fd(self.log, command, stdout, 'Local stdout')
|
util.log_std_fd(self.log, command, stdout, 'Local stdout')
|
||||||
return output
|
return output
|
||||||
except subprocess.CalledProcessError as e:
|
except (OSError, subprocess.CalledProcessError) as error:
|
||||||
util.handle_called_process_error(e, command)
|
raise cdist.Error(" ".join(command) + ": " + str(error.args[1]))
|
||||||
except OSError as error:
|
|
||||||
raise cdist.Error(" ".join(command) + ": " + error.args[1])
|
|
||||||
finally:
|
finally:
|
||||||
if message_prefix:
|
if message_prefix:
|
||||||
message.merge_messages()
|
message.merge_messages()
|
||||||
|
|
|
@ -343,10 +343,8 @@ class Remote(object):
|
||||||
util.log_std_fd(self.log, command, stdout, 'Remote stdout')
|
util.log_std_fd(self.log, command, stdout, 'Remote stdout')
|
||||||
|
|
||||||
return output
|
return output
|
||||||
except subprocess.CalledProcessError as e:
|
except (OSError, subprocess.CalledProcessError) as error:
|
||||||
util.handle_called_process_error(e, command)
|
raise cdist.Error(" ".join(command) + ": " + str(error.args[1]))
|
||||||
except OSError as error:
|
|
||||||
raise cdist.Error(" ".join(command) + ": " + error.args[1])
|
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
raise DecodeError(command)
|
raise DecodeError(command)
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -127,6 +127,7 @@ def call_get_output(command, env=None, stderr=None):
|
||||||
return (_call_get_stdout(command, env, stderr), None)
|
return (_call_get_stdout(command, env, stderr), None)
|
||||||
|
|
||||||
|
|
||||||
|
# Currently not used.
|
||||||
def handle_called_process_error(err, command):
|
def handle_called_process_error(err, command):
|
||||||
# Currently, stderr is not captured.
|
# Currently, stderr is not captured.
|
||||||
# errout = None
|
# errout = None
|
||||||
|
|
Loading…
Reference in a new issue