Skip to content

Commit 95d074a

Browse files
committed
Improve error output from failing external programs (fix #20)
Print any stderr output from the program that failed, and make the command that was run more legible in Nancy’s error message.
1 parent 4da3861 commit 95d074a

File tree

4 files changed

+40
-22
lines changed

4 files changed

+40
-22
lines changed

nancy/__init__.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,18 @@ def filter_bytes(
181181
exe_path = Path(exe_path_str)
182182
exe_args = external_args[1:]
183183
debug(f"Running {exe_path} {b' '.join(exe_args)}")
184-
res = subprocess.run(
185-
[exe_path.resolve(strict=True)] + exe_args,
186-
capture_output=True,
187-
check=True,
188-
input=input,
189-
)
190-
return res.stdout
184+
try:
185+
res = subprocess.run(
186+
[exe_path.resolve(strict=True)] + exe_args,
187+
capture_output=True,
188+
check=True,
189+
input=input,
190+
)
191+
return res.stdout
192+
except subprocess.CalledProcessError as err:
193+
if err.stderr is not None:
194+
print(err.stderr.decode("iso-8859-1"), file=sys.stderr)
195+
die(f"Error code {err.returncode} running: {' '.join(map(str, err.cmd))}")
191196

192197
def command_to_str(
193198
name: bytes,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
printf "oh no!" >&2
3+
exit 1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$run(fail-with-error.in.sh)

tests/test_nancy.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,11 @@
1313
from unittest import mock
1414

1515
import pytest
16+
from nancy import main
1617
from pytest import CaptureFixture, LogCaptureFixture
17-
from testutils import (
18-
check_links,
19-
failing_cli_test,
20-
failing_test,
21-
passing_cli_test,
22-
passing_test,
23-
)
2418

25-
from nancy import main
19+
from testutils import (check_links, failing_cli_test, failing_test,
20+
passing_cli_test, passing_test)
2621

2722

2823
if sys.version_info[:2] >= (3, 11): # pragma: no cover
@@ -72,13 +67,6 @@ def test_expand_of_run_output() -> None:
7267
passing_test(["expand-run-src"], "expand-run-expected")
7368

7469

75-
def test_failing_executable_test() -> None:
76-
with chdir(tests_dir):
77-
failing_test(
78-
[os.getcwd()], "returned non-zero exit status 1", "false.nancy.txt"
79-
)
80-
81-
8270
def test_non_existent_executable_test() -> None:
8371
with chdir(tests_dir):
8472
failing_test([os.getcwd()], "cannot find program 'foo'", "foo.nancy.txt")
@@ -350,6 +338,27 @@ def test_invalid_command_line_argument_causes_an_error(
350338
failing_cli_test(capsys, caplog, ["--foo", "a"], "unrecognized arguments: --foo")
351339

352340

341+
def test_failing_executable_test(
342+
capsys: CaptureFixture[str],
343+
caplog: LogCaptureFixture,
344+
) -> None:
345+
with chdir(tests_dir):
346+
failing_cli_test(capsys, caplog, ["false.nancy.txt"], "Error code 1")
347+
348+
349+
def test_failing_executable_error_message_test(
350+
capsys: CaptureFixture[str],
351+
caplog: LogCaptureFixture,
352+
) -> None:
353+
with chdir(tests_dir):
354+
failing_cli_test(
355+
capsys,
356+
caplog,
357+
["fail-with-error.nancy.txt"],
358+
"oh no!",
359+
)
360+
361+
353362
def test_running_on_a_nonexistent_path_causes_an_error_DEBUG_coverage(
354363
capsys: CaptureFixture[str],
355364
caplog: LogCaptureFixture,

0 commit comments

Comments
 (0)