如何处理 picocli 中的错误?
How can I handle errors in picocli?
我尝试实现我自己的 CLI 并想使用 picocli 来解析我的命令的参数。这就是为什么我根本不想让 picocli 在控制台中写入。所以我用一些选项和参数注释创建了 class MyCommand
。现在我希望能够做这样的事情:
val myCommand = CommandLine.populateCommand(MyCommand(), args)
myCommand.execute();
val output = myCommand.getOutput();
val errors: List<String> = myCommand.getErrors();
前三行没有问题,但我不知道如何处理第四行。现在 populateCommand
只是抛出所有异常,捕获它们不是一种选择,因为抛出的异常会停止我的管道计算。 Picocli 文档建议使用解析器宽松模式将异常存储在 ParseResult
中,但这意味着我必须使用 commandLine.parseWithHandlers
方法,这很难满足我的需要。
我错过了什么吗?也许我仍然可以使用 populateCommand
并将异常存储在某个地方?
这是 populateCommand
抛出的异常之一的堆栈跟踪:
Exception in thread "main" picocli.CommandLine$MissingParameterException: Missing required parameter for option '-A' (<afterContext>)
at picocli.CommandLine$Interpreter.assertNoMissingParameters(CommandLine.java:8059)
at picocli.CommandLine$Interpreter.applyOption(CommandLine.java:7534)
at picocli.CommandLine$Interpreter.processStandaloneOption(CommandLine.java:7446)
at picocli.CommandLine$Interpreter.processArguments(CommandLine.java:7355)
at picocli.CommandLine$Interpreter.parse(CommandLine.java:7226)
at picocli.CommandLine$Interpreter.parse(CommandLine.java:7116)
at picocli.CommandLine.parse(CommandLine.java:824)
at picocli.CommandLine.populateCommand(CommandLine.java:777)
Ignoring parsing errors is unusual, but can be useful when creating
your own interactive CLI console, as opposed to a single command. My answer assumes this is what you have in mind.
一个想法是使用 parseArgs
方法而不是 populateCommand
方法。此方法 returns a ParseResult
如果您已将解析器配置为宽松,您可以从中获取 picocli 在解析过程中遇到的错误。
例如:
val myCommand = MyCommand();
val commandLine = CommandLine(myCommand);
// tell parser to be lenient
commandLine.getCommandSpec().parser().collectErrors(true);
// parse user input, query result for errors
val parseResult = commandLine.parseArgs(args);
val parseErrors: List<Exception> = parseResult.errors();
// ignoring the errors for now...
myCommand.execute();
val output = myCommand.getOutput();
val appErrors: List<String> = myCommand.getErrors();
Note that if there are any parsing errors, this means that the user
specified invalid input. As a result, your command may not have been
correctly initialized. The execute
method needs to be extra robust
to deal with partially initialized options/positional parameters.
提示:如果您要创建自己的 interactive CLI 控制台(而不是单个命令),您可能会对 JLine 2 (requires Java 5 or higher) or JLine 3 (requires Java 8 or higher). Picocli provides picocli-shell-jline2 and picocli-shell-jline3 modules that have a PicocliJLineCompleter
that shows context-sensitive completion candidates for picocli commands. (The readme of each module has an example.) Applications that use picocli to define their commands no longer need to hand-code Completers for their commands and options. (An early version of this is used in the Micronaut CLI.)
我尝试实现我自己的 CLI 并想使用 picocli 来解析我的命令的参数。这就是为什么我根本不想让 picocli 在控制台中写入。所以我用一些选项和参数注释创建了 class MyCommand
。现在我希望能够做这样的事情:
val myCommand = CommandLine.populateCommand(MyCommand(), args)
myCommand.execute();
val output = myCommand.getOutput();
val errors: List<String> = myCommand.getErrors();
前三行没有问题,但我不知道如何处理第四行。现在 populateCommand
只是抛出所有异常,捕获它们不是一种选择,因为抛出的异常会停止我的管道计算。 Picocli 文档建议使用解析器宽松模式将异常存储在 ParseResult
中,但这意味着我必须使用 commandLine.parseWithHandlers
方法,这很难满足我的需要。
我错过了什么吗?也许我仍然可以使用 populateCommand
并将异常存储在某个地方?
这是 populateCommand
抛出的异常之一的堆栈跟踪:
Exception in thread "main" picocli.CommandLine$MissingParameterException: Missing required parameter for option '-A' (<afterContext>)
at picocli.CommandLine$Interpreter.assertNoMissingParameters(CommandLine.java:8059)
at picocli.CommandLine$Interpreter.applyOption(CommandLine.java:7534)
at picocli.CommandLine$Interpreter.processStandaloneOption(CommandLine.java:7446)
at picocli.CommandLine$Interpreter.processArguments(CommandLine.java:7355)
at picocli.CommandLine$Interpreter.parse(CommandLine.java:7226)
at picocli.CommandLine$Interpreter.parse(CommandLine.java:7116)
at picocli.CommandLine.parse(CommandLine.java:824)
at picocli.CommandLine.populateCommand(CommandLine.java:777)
Ignoring parsing errors is unusual, but can be useful when creating your own interactive CLI console, as opposed to a single command. My answer assumes this is what you have in mind.
一个想法是使用 parseArgs
方法而不是 populateCommand
方法。此方法 returns a ParseResult
如果您已将解析器配置为宽松,您可以从中获取 picocli 在解析过程中遇到的错误。
例如:
val myCommand = MyCommand();
val commandLine = CommandLine(myCommand);
// tell parser to be lenient
commandLine.getCommandSpec().parser().collectErrors(true);
// parse user input, query result for errors
val parseResult = commandLine.parseArgs(args);
val parseErrors: List<Exception> = parseResult.errors();
// ignoring the errors for now...
myCommand.execute();
val output = myCommand.getOutput();
val appErrors: List<String> = myCommand.getErrors();
Note that if there are any parsing errors, this means that the user specified invalid input. As a result, your command may not have been correctly initialized. The
execute
method needs to be extra robust to deal with partially initialized options/positional parameters.
提示:如果您要创建自己的 interactive CLI 控制台(而不是单个命令),您可能会对 JLine 2 (requires Java 5 or higher) or JLine 3 (requires Java 8 or higher). Picocli provides picocli-shell-jline2 and picocli-shell-jline3 modules that have a PicocliJLineCompleter
that shows context-sensitive completion candidates for picocli commands. (The readme of each module has an example.) Applications that use picocli to define their commands no longer need to hand-code Completers for their commands and options. (An early version of this is used in the Micronaut CLI.)