Skip to content

Commit f0d74c2

Browse files
fix: dispatch subprocess.run now catches 'No module named' in stderr instead of relying on FileNotFoundError
reviewer-A missed that subprocess.run never raises FileNotFoundError when a Python module is absent — it returns exit code 1 with 'No module named' in stderr. The old code's except FileNotFoundError was dead code, causing users to see a raw Python error instead of the friendly install prompt. Also switched capture_output to True with text=True so stderr is readable, and added proper stdout/stderr passthrough for successful and failed runs.
1 parent a773e53 commit f0d74c2

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

src/devforge/cli.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,27 @@ def dispatch(
155155
try:
156156
result = subprocess.run(
157157
[sys.executable, "-m", info["package"].replace("-", "_")] + (args or []),
158-
capture_output=False,
158+
capture_output=True,
159+
text=True,
159160
)
161+
if result.returncode == 0:
162+
sys.stdout.write(result.stdout)
163+
if result.stderr:
164+
sys.stderr.write(result.stderr)
165+
sys.exit(0)
166+
# Module not found — show friendly install message
167+
if "No module named" in result.stderr:
168+
console.print(
169+
f"[red]Tool '{tool_name}' not installed.[/red]\n"
170+
f"Install with: [green]pip install devforge-tools[{tool_name}][/green]"
171+
)
172+
raise typer.Exit(code=1) from None
173+
# Tool ran but failed — show its output and propagate exit code
174+
sys.stdout.write(result.stdout)
175+
sys.stderr.write(result.stderr)
160176
sys.exit(result.returncode)
161177
except FileNotFoundError:
178+
# Only reached if sys.executable itself is missing (extremely rare)
162179
console.print(
163180
f"[red]Tool '{tool_name}' not installed.[/red]\n"
164181
f"Install with: [green]pip install devforge-tools[{tool_name}][/green]"

0 commit comments

Comments
 (0)