Unmatched argument returned when no equal sign used with option using a converter
See original GitHub issueIssue noticed in app using PicoCLI Java 3.9.2 but also experienced with latest info.picocli:picocli:3.9.5.
Command line option code looks like this :
@Option(
names = {"--bootnodes"},
split = ",",
arity = "0..*",
converter = EnodeToURIPropertyConverter.class)
private final Collection<URI> bootNodes = null;
I’m skipping some useless details as not necessary for our story, but feel free to ask, the code is open source and can be seen at https://github.com/PegaSysEng/pantheon/blob/1966f485739ed75e4a8da8b95cd6a0afd2b365af/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java#L181
This option takes a list of enode strings separated by commas as input, or nothing if you want to override the default value. Default value is provided by an IDefaultValueProvider not visible here.
Our converter transforms a string to a URI using. This converter first check the string using a regex and com.google.common.base.Preconditions#checkArgument(boolean, java.lang.Object)
if there’s any issue checkArgument throws an IllegalArgumentException(reason of the failure)
If you run pantheon --bootnodes enode://d2567893371ea5a6fa6371d483891ed0d129e79a8fc74d6df95a00a6545444cd4a6960bbffe0b4e2edcf35135271de57ee559c0909236bbc2074346ef2b5b47c@127.0.0.1:30304
this works as the input format is ok.
But if you run for instance pantheon --bootnodes enode://invalidid@127.0.0.1:30304
, the format being wrong it return :
Unmatched argument: enode://invalidid@127.0.0.1:30304
Did you mean: public-key?
It proposes public-key
subcommand as a possible argument because it’s probably the closest thing it found but yet we don’t have any idea of the issue in the argument.
However, the strange thing, and that’s where it becomes interesting, is that when we call the program with same command pantheon --bootnodes=enode://invalidid@127.0.0.1:30304
but with an equal sign between the option and the value, it returns the full issue message Invalid value for option '--bootnodes' at index 0 (<enode://id@host:port>): cannot convert 'enode://invalidid@127.0.0.1:30304' to URI (java.lang.IllegalArgumentException: Enode URL contains an invalid node ID. Node ID must have 128 characters and shouldn't include the '0x' hex prefix.)
which is what we want to enable users to understand why it fails.
So having the equal sign here changes how it handles the error. I guess it’s related to arity as we enable the option to have no value, but it seems to be related to the converter too as it work totally fine it you do this without a converter and an option of Collection<String> type.
Any idea where I can search ?
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (8 by maintainers)
I implemented your last proposal with just a change that I don’t use a converter but just a lambda and handle the error in the option method. I prefer to keep this that way for the moment as we are planning a refactoring soon. And it works like a charm. Thanks for your (as usual, always) very efficient help.
One could argue that even the error handling could (and perhaps should) be pushed into the converter. That would leave you with very simple code in the annotated option setter method: