Как заставить команду Spring Shell провалиться?
Представьте, что у меня есть следующий класс команд Spring Shell:
import org.springframework.shell.core.CommandMarker;
@Component
public class MyShellCommands implements CommandMarker {
@CliCommand(value = COMMAND_RUN, help = "")
public String run() {
[...]
// Something can go wrong here
[...]
}
}
Если в методе возникает какая-либо ошибка, я хочу, чтобы команда завершилась неудачно.
Как я могу сделать run
сбой команды, т.е. убедитесь, что в случае ошибки в команде, следующее утверждение не выполнится:
JLineShellComponent shell = ...;
final CommandResult result = shell.executeCommand("run");
assertThat(result.isSuccess()).isTrue(); // I want result.isSuccess() to be false, if run fails
?
2 ответа
Создание исключения во время выполнения работает, вы даже сможете получить его через CommandResult.getException()
Вот код из Spring -Shell, где CommandResult имеет значение true или false.
Просто поищите вхождения return new CommandResult(false...
и попытайтесь выяснить, можете ли вы вызвать какой-либо из сценариев, которые приведут к этому.
Например, я заметил, что если parseResult == null
тогда устанавливается ложный статус.
public CommandResult executeCommand(String line) {
// Another command was attempted
setShellStatus(ShellStatus.Status.PARSING);
final ExecutionStrategy executionStrategy = getExecutionStrategy();
boolean flashedMessage = false;
while (executionStrategy == null || !executionStrategy.isReadyForCommands()) {
// Wait
try {
Thread.sleep(500);
} catch (InterruptedException ignore) {}
if (!flashedMessage) {
flash(Level.INFO, "Please wait - still loading", MY_SLOT);
flashedMessage = true;
}
}
if (flashedMessage) {
flash(Level.INFO, "", MY_SLOT);
}
ParseResult parseResult = null;
try {
// We support simple block comments; ie a single pair per line
if (!inBlockComment && line.contains("/*") && line.contains("*/")) {
blockCommentBegin();
String lhs = line.substring(0, line.lastIndexOf("/*"));
if (line.contains("*/")) {
line = lhs + line.substring(line.lastIndexOf("*/") + 2);
blockCommentFinish();
} else {
line = lhs;
}
}
if (inBlockComment) {
if (!line.contains("*/")) {
return new CommandResult(true);
}
blockCommentFinish();
line = line.substring(line.lastIndexOf("*/") + 2);
}
// We also support inline comments (but only at start of line, otherwise valid
// command options like http://www.helloworld.com will fail as per ROO-517)
if (!inBlockComment && (line.trim().startsWith("//") || line.trim().startsWith("#"))) { // # support in ROO-1116
line = "";
}
// Convert any TAB characters to whitespace (ROO-527)
line = line.replace('\t', ' ');
if ("".equals(line.trim())) {
setShellStatus(Status.EXECUTION_SUCCESS);
return new CommandResult(true);
}
parseResult = getParser().parse(line);
if (parseResult == null) {
return new CommandResult(false);
}
setShellStatus(Status.EXECUTING);
Object result = executionStrategy.execute(parseResult);
setShellStatus(Status.EXECUTION_RESULT_PROCESSING);
if (result != null) {
if (result instanceof ExitShellRequest) {
exitShellRequest = (ExitShellRequest) result;
// Give ProcessManager a chance to close down its threads before the overall OSGi framework is terminated (ROO-1938)
executionStrategy.terminate();
} else {
handleExecutionResult(result);
}
}
logCommandIfRequired(line, true);
setShellStatus(Status.EXECUTION_SUCCESS, line, parseResult);
return new CommandResult(true, result, null);
} catch (RuntimeException e) {
setShellStatus(Status.EXECUTION_FAILED, line, parseResult);
// We rely on execution strategy to log it
try {
logCommandIfRequired(line, false);
} catch (Exception ignored) {}
return new CommandResult(false, null, e);
} finally {
setShellStatus(Status.USER_INPUT);
}
}