Skip to content

Commit 8f312a6

Browse files
committed
Report failed launches as exit code 127 instead of throwing
With direct argv, a missing or non-executable command makes ProcessBuilder.start() throw, where the removed shell wrapper used to start and exit with an error code. Callers (e.g., ProcessExecution, SpecsGraphviz dot detection) relied on receiving a non-zero return value instead of an exception, so mirror the shell behavior: return a ProcessOutput with exit code 127 and the failure message on stderr.
1 parent b54f698 commit 8f312a6

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

SpecsUtils/src/pt/up/fe/specs/util/SpecsSystem.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
import pt.up.fe.specs.util.utilities.JarPath;
2424
import pt.up.fe.specs.util.utilities.ProgressCounter;
2525

26+
import java.io.ByteArrayInputStream;
2627
import java.io.File;
2728
import java.io.IOException;
2829
import java.io.InputStream;
2930
import java.io.OutputStream;
31+
import java.nio.charset.StandardCharsets;
3032
import java.lang.invoke.MethodHandles;
3133
import java.lang.invoke.MethodHandles.Lookup;
3234
import java.lang.invoke.VarHandle;
@@ -190,10 +192,20 @@ public static <O, E> ProcessOutput<O, E> runProcess(ProcessBuilder builder,
190192

191193
Process process;
192194
try {
193-
process = builder.start();
195+
process = builder.start();
194196

195197
} catch (IOException e) {
196-
throw new RuntimeException("Could not start process", e);
198+
// The command could not be executed (e.g., not found, not executable).
199+
// A shell launcher would have started and exited with an error code
200+
// (127 for not found), so report failure the same way instead of throwing.
201+
SpecsLogs.msgInfo("Could not start process: " + e.getMessage());
202+
try (InputStream emptyOut = new ByteArrayInputStream(new byte[0]);
203+
InputStream emptyErr = new ByteArrayInputStream(
204+
("Could not start process: " + e.getMessage()).getBytes(StandardCharsets.UTF_8))) {
205+
return new ProcessOutput<>(127, outputProcessor.apply(emptyOut), errorProcessor.apply(emptyErr));
206+
} catch (IOException e2) {
207+
throw new RuntimeException("Could not build error output for failed launch", e2);
208+
}
197209
}
198210

199211
ExecutorService stdoutThread = Executors.newSingleThreadExecutor();

0 commit comments

Comments
 (0)