Skip to content

Commit 70b96f6

Browse files
committed
chore: Various improvements
1 parent ee23d94 commit 70b96f6

File tree

3 files changed

+66
-12
lines changed

3 files changed

+66
-12
lines changed

fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FcliCommandExecutorFactory.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.slf4j.LoggerFactory;
2727

2828
import com.fasterxml.jackson.databind.node.ObjectNode;
29+
import com.fortify.cli.common.exception.FcliCommandExecutionException;
2930
import com.fortify.cli.common.exception.FcliExecutionExceptionHandler;
3031
import com.fortify.cli.common.exception.FcliSimpleException;
3132
import com.fortify.cli.common.output.cli.cmd.IRecordCollectionSupport;
@@ -192,7 +193,7 @@ private void rethrowAsRuntimeException(Throwable t) {
192193
}
193194

194195
private final void throwExceptionOnNonZeroExitCode(Result r) {
195-
throw new FcliSimpleException("Fcli command terminated with non-zero exit code "+r.getExitCode());
196+
throw new FcliCommandExecutionException(r);
196197
}
197198

198199
// We want to replicate the CommandSpec with new command instances, at least for the
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2021-2025 Open Text.
3+
*
4+
* The only warranties for products and services of Open Text
5+
* and its affiliates and licensors ("Open Text") are as may
6+
* be set forth in the express warranty statements accompanying
7+
* such products and services. Nothing herein should be construed
8+
* as constituting an additional warranty. Open Text shall not be
9+
* liable for technical or editorial errors or omissions contained
10+
* herein. The information contained herein is subject to change
11+
* without notice.
12+
*/
13+
package com.fortify.cli.common.exception;
14+
15+
import com.formkiq.graalvm.annotations.Reflectable;
16+
import com.fortify.cli.common.util.OutputHelper;
17+
18+
import lombok.Getter;
19+
20+
/**
21+
* Exception thrown when an fcli command execution fails with a non-zero exit code.
22+
* Provides access to the command's stdout and stderr output for detailed error reporting.
23+
*/
24+
@Reflectable
25+
public class FcliCommandExecutionException extends FcliSimpleException {
26+
private static final long serialVersionUID = 1L;
27+
28+
@Getter
29+
private final OutputHelper.Result result;
30+
31+
public FcliCommandExecutionException(OutputHelper.Result result) {
32+
super("Command execution failed with exit code " + result.getExitCode());
33+
this.result = result;
34+
}
35+
36+
public FcliCommandExecutionException(String message, OutputHelper.Result result) {
37+
super(message);
38+
this.result = result;
39+
}
40+
}

fcli-core/fcli-tool/src/main/java/com/fortify/cli/tool/setup/cli/cmd/ToolSetupCommand.java

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.fortify.cli.common.cli.cmd.AbstractRunnableCommand;
1919
import com.fortify.cli.common.cli.util.FcliCommandExecutorFactory;
20+
import com.fortify.cli.common.exception.FcliCommandExecutionException;
2021
import com.fortify.cli.common.exception.FcliSimpleException;
2122
import com.fortify.cli.common.util.JreHelper;
2223
import com.fortify.cli.common.util.OutputHelper;
@@ -142,9 +143,13 @@ private RegistrationResult tryRegisterTool(ToolSetupSpec spec, String version) {
142143
String installDir = extractInstallDirFromJsonOutput(result.getOut());
143144
return new RegistrationResult(true, installDir != null ? installDir : "PATH");
144145
}
145-
} catch (Exception e) {
146+
} catch (FcliCommandExecutionException e) {
146147
// Registration failed, but don't throw - just log progress
147148
System.out.println("Tool " + toolName + " not found in PATH, will proceed with installation");
149+
// Do not show stderr for expected registration failures
150+
} catch (Exception e) {
151+
// Other exceptions
152+
System.out.println("Tool " + toolName + " not found in PATH, will proceed with installation");
148153
}
149154
return new RegistrationResult(false, null);
150155
}
@@ -186,16 +191,24 @@ private InstallResult installTool(ToolSetupSpec spec, String version) {
186191
}
187192
}
188193

189-
var result = executeFcliCommand(cmd);
190-
if (result.getExitCode() != 0) {
191-
throw new FcliSimpleException("Failed to install " + toolName);
194+
try {
195+
var result = executeFcliCommand(cmd);
196+
197+
// Extract action and install directory from JSON output
198+
String action = extractActionFromJsonOutput(result.getOut());
199+
String installDir = extractInstallDirFromJsonOutput(result.getOut());
200+
201+
return new InstallResult(action != null ? action : "installed", installDir != null ? installDir : "installed");
202+
} catch (FcliCommandExecutionException e) {
203+
// Show user-friendly error message
204+
System.err.println("Installation for " + toolName + " failed:");
205+
if (e.getResult().getErr() != null && !e.getResult().getErr().isEmpty()) {
206+
System.err.println(e.getResult().getErr());
207+
} else if (e.getResult().getOut() != null && !e.getResult().getOut().isEmpty()) {
208+
System.err.println(e.getResult().getOut());
209+
}
210+
throw new FcliSimpleException("Installation of " + toolName + " failed");
192211
}
193-
194-
// Extract action and install directory from JSON output
195-
String action = extractActionFromJsonOutput(result.getOut());
196-
String installDir = extractInstallDirFromJsonOutput(result.getOut());
197-
198-
return new InstallResult(action != null ? action : "installed", installDir != null ? installDir : "installed");
199212
}
200213

201214
private String extractInstallDirFromJsonOutput(String output) {
@@ -325,7 +338,7 @@ private OutputHelper.Result executeFcliCommand(String cmd) {
325338
var executor = FcliCommandExecutorFactory.builder()
326339
.cmd(cmd)
327340
.stdoutOutputType(OutputType.collect) // Collect stdout to get the JSON output
328-
.stderrOutputType(OutputType.suppress) // Suppress stderr to avoid showing exceptions
341+
.stderrOutputType(OutputType.collect) // Collect stderr to show on failure
329342
.build()
330343
.create();
331344
return executor.execute();

0 commit comments

Comments
 (0)