Skip to content
Snippets Groups Projects
Commit 062fd1da authored by John Snow's avatar John Snow Committed by Hanna Reitz
Browse files

python/utils: add VerboseProcessError


This adds an Exception that extends the Python stdlib
subprocess.CalledProcessError.

The difference is that the str() method of this exception also adds the
stdout/stderr logs. In effect, if this exception goes unhandled, Python
will print the output in a visually distinct wrapper to the terminal so
that it's easy to spot in a sea of traceback information.

Signed-off-by: default avatarJohn Snow <jsnow@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Reviewed-by: default avatarHanna Reitz <hreitz@redhat.com>
Message-Id: <20220321201618.903471-3-jsnow@redhat.com>
Signed-off-by: default avatarHanna Reitz <hreitz@redhat.com>
parent be73231b
No related branches found
No related tags found
No related merge requests found
......@@ -18,6 +18,7 @@
import os
import re
import shutil
from subprocess import CalledProcessError
import textwrap
from typing import Optional
......@@ -26,6 +27,7 @@
__all__ = (
'VerboseProcessError',
'add_visual_margin',
'get_info_usernet_hostfwd_port',
'kvm_available',
......@@ -121,3 +123,40 @@ def _wrap(line: str) -> str:
os.linesep.join(_wrap(line) for line in content.splitlines()),
_bar(None, top=False),
))
class VerboseProcessError(CalledProcessError):
"""
The same as CalledProcessError, but more verbose.
This is useful for debugging failed calls during test executions.
The return code, signal (if any), and terminal output will be displayed
on unhandled exceptions.
"""
def summary(self) -> str:
"""Return the normal CalledProcessError str() output."""
return super().__str__()
def __str__(self) -> str:
lmargin = ' '
width = -len(lmargin)
sections = []
# Does self.stdout contain both stdout and stderr?
has_combined_output = self.stderr is None
name = 'output' if has_combined_output else 'stdout'
if self.stdout:
sections.append(add_visual_margin(self.stdout, width, name))
else:
sections.append(f"{name}: N/A")
if self.stderr:
sections.append(add_visual_margin(self.stderr, width, 'stderr'))
elif not has_combined_output:
sections.append("stderr: N/A")
return os.linesep.join((
self.summary(),
textwrap.indent(os.linesep.join(sections), prefix=lmargin),
))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment