-
Notifications
You must be signed in to change notification settings - Fork 418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IExecutionExceptionHandler
does not provided parsed ParseResult
#2228
Comments
@abelsromero Thank you for raising this. I will take a look. |
@abelsromero I am looking at this now. I think I see the cause of the issue. Would you be able to provide a failing test? That would be very helpful. |
I'll see to get some time this week, just don't expect it until the weekend. |
I added a test, but it succeeds even before I make changes to fix the issue. Re-reading your comments now I have some idea on how to improve the test, I will iterate when I have time to work on this again. |
I seem unable to reproduce the issue... |
Thanks for the patience and time! I admit I am confused with your test You mention the test does not reproduce, but the code and running locally shows the values are empty. Maybe I am assuming something that this not true? Oddly however, still empty after running parse 🤔 Here's an example https://github.com/abelsromero/picocli-reproducer with further explanation. See the different in output for both the parseResult injected and the one obtained from |
I do not see empty values (and the test passes, proving that the list is not empty:
Are you getting different results?
@abelsromero I have not had a chance to check out and build your project yet. Can you post the input you provided and the output that you are seeing from your reproducer? |
I have been able to run your reproducer project and I get this output:
I will investigate further. |
My mistake, I misread the assertion seeing the empty at the end.
Thanks! I was doing some extra tests in my reproducer and I think the issue stems from the use of @CommandLine.Command(
// subcommands = {
// ListCommand.class,
// GetCommand.class
// },
description = "Test CLI")
public class ParentCommand {
@CommandLine.Option(names = {"-n", "--num"})
protected Integer num;
} I get results
|
Modified the test to reproduce package picocli;
import org.junit.Test;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParseResult;
import java.util.List;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
public class Issue2228 {
@Command(
subcommands = {
SubCommand.class
})
static class TestCommand {
}
@Command(name = "subsub")
static class SubCommand implements Runnable {
@Option(names = "-y")
public boolean y;
public void run() {
throw new IllegalStateException("Y failing, just for fun");
}
}
@Test
public void testParseResult() {
final CommandLine commandLine = new CommandLine(new Issue2228.TestCommand());
final ParseResult[] caughtParseResult = new ParseResult[1];
commandLine.setExecutionExceptionHandler(new CommandLine.IExecutionExceptionHandler() {
public int handleExecutionException(Exception ex, CommandLine exCmdLine, ParseResult parseResult) throws Exception {
// assertSame(commandLine, exCmdLine);
assertNotNull(parseResult);
List<CommandLine.Model.ArgSpec> argSpecs = parseResult.matchedArgs();
List<CommandLine.Model.OptionSpec> optionSpecs = parseResult.matchedOptions();
caughtParseResult[0] = parseResult;
return 0;
}
});
commandLine.execute("subsub");
assertNotNull(caughtParseResult[0]);
ParseResult after = commandLine.getParseResult();
assertFalse(after.matchedArgs().isEmpty());
assertFalse(after.matchedOptions().isEmpty());
assertFalse(caughtParseResult[0].matchedArgs().isEmpty());
assertFalse(caughtParseResult[0].matchedOptions().isEmpty());
}
} Line 40 |
Thank you for that! Now I see what is happening: The This is inconsistent with the I will change it so that the |
@abelsromero I was about to make this change, but now I am having second thoughts. Another way to solve this issue would be to clarify the current behaviour in the documentation; Some thing like this:
Thoughts? |
Firstly, if this is a breaking change, it's fine to delay for a major release. Then, also breaking change, why not remove |
I am very, very hesitant to break anyone's application, even in major releases. The problem is not that the current behaviour is broken, it is simply not defined clearly enough: Note also that the ParseResult class was designed to be navigated top-down, using its I can see the inconsistency with the However, rather than changing the API, I lean towards clarifying the documentation. |
That's the issue to me, it does not fully address the problem. But said that, matching the current command will be fine for most users. It can be done and see how community reacts. |
Looking into how to handle exceptions (https://picocli.info/#_invalid_user_input) I'd like to add some behavior depending on an argument. But
parseResult
in the method handleException in IExecutionExceptionHandler does not contain the actual parsed input. InsteadmatchedArgs()
andmatchedOptions
return empty and onlyoriginalArgs()
returns something.As a workaround, I am calling
commandLine.getParseResult()
which provides the actual input command parsed.The expectation would be that the workaround is not necessary and the parameter from the method provides such information.
The text was updated successfully, but these errors were encountered: