diff --git a/docs/changelog/3450.bugfix.rst b/docs/changelog/3450.bugfix.rst new file mode 100644 index 000000000..10ef74a1d --- /dev/null +++ b/docs/changelog/3450.bugfix.rst @@ -0,0 +1,3 @@ +Log exception name when subprocess execution produces one. + +- by :user:`ssbarnea` diff --git a/src/tox/execute/local_sub_process/__init__.py b/src/tox/execute/local_sub_process/__init__.py index 2661fc9ab..8fa11c49c 100644 --- a/src/tox/execute/local_sub_process/__init__.py +++ b/src/tox/execute/local_sub_process/__init__.py @@ -214,6 +214,9 @@ def __enter__(self) -> ExecuteStatus: env=self.request.env, ) except OSError as exception: + # We log a nice error message to avout returning opaque error codes, + # like exit code 2 (filenotfound). + logging.error("Exception running subprocess %s", str(exception)) # noqa: TRY400 return LocalSubprocessExecuteFailedStatus(self.options, self._out, self._err, exception.errno) status = LocalSubprocessExecuteStatus(self.options, self._out, self._err, process) diff --git a/tests/execute/local_subprocess/test_local_subprocess.py b/tests/execute/local_subprocess/test_local_subprocess.py index 7795d70a7..ef0d00d7b 100644 --- a/tests/execute/local_subprocess/test_local_subprocess.py +++ b/tests/execute/local_subprocess/test_local_subprocess.py @@ -4,6 +4,7 @@ import locale import logging import os +import re import shutil import stat import subprocess @@ -264,7 +265,11 @@ def test_command_does_not_exist(caplog: LogCaptureFixture, os_env: dict[str, str assert outcome.exit_code != Outcome.OK assert not outcome.out assert not outcome.err - assert not caplog.records + assert len(caplog.records) == 1 + assert caplog.records[0].levelname == "ERROR" + assert re.match( + r".*(No such file or directory|The system cannot find the file specified).*", caplog.records[0].message + ) @pytest.mark.skipif(sys.platform == "win32", reason="You need a conhost shell for keyboard interrupt")