Ruiqi Dong created CLI-342: ------------------------------ Summary: Parser fails to throw MissingArgumentException for empty required arguments when parsing via Properties Key: CLI-342 URL: https://issues.apache.org/jira/browse/CLI-342 Project: Commons CLI Issue Type: Bug Components: Parser Affects Versions: 1.10.0 Reporter: Ruiqi Dong Fix For: 1.10.0 Attachments: Parser.java, ParserTest.java
The {{Parser}} class silently ignores invalid/empty argument values when parsing options through Properties, while the same scenario correctly throws {{MissingArgumentException}} when parsing via command line arguments. This inconsistent behavior is caused by a catch block that swallows {{RuntimeException}} in the {{processProperties}} method. Description: When parsing options that require arguments through Properties, if an empty or invalid value is provided, the parser does not throw a {{MissingArgumentException}} as expected. Instead, the exception is silently swallowed due to a catch block in the {{processProperties}} method. This creates inconsistent behavior between command-line parsing and Properties-based parsing. Steps to Reproduce: 1. Create an Option that requires an argument: Options options = new Options(); Option option = new Option("f", "file", true, "Input file"); options.addOption(option); 2. Parse via Properties with empty value: Properties properties = new Properties(); properties.setProperty("file", ""); Parser parser = new PosixParser(); CommandLine cmd = parser.parse(options, new String[0], properties); 3. No exception is thrown, but the option has no valid value Expected Behavior: The parser should throw a {{MissingArgumentException}} when a required argument is missing or empty, consistent with command-line parsing behavior. Actual Behavior: No exception is thrown. The RuntimeException is caught and silently ignored in the {{processProperties}} method. Unit Test Case: @Test void testEmptyArgumentViaPropertiesShouldThrowException() { Options options = new Options(); Option option = new Option("f", "file", true, "Input file"); options.addOption(option); Properties properties = new Properties(); properties.setProperty("file", ""); Parser parser = new PosixParser(); // This should throw ParseException but doesn't assertThrows(ParseException.class, () -> { parser.parse(options, new String[0], properties); }); } Root Cause Analysis: In {{{}Parser.java{}}}, the {{processProperties}} method contains: if (opt.hasArg()) { if (Util.isEmpty(opt.getValues())) { try { opt.processValue(value); } catch (final RuntimeException exp) { // NOPMD // if we cannot add the value don't worry about it } } } The catch block silently swallows any {{RuntimeException}} thrown by {{{}processValue(){}}}, including cases where the value is invalid or empty. When parsing via command line, the {{processArgs}} method correctly handles this: if (opt.getValues() == null && !opt.hasOptionalArg()) { throw new MissingArgumentException(opt); } Suggested Fix: Remove or modify the exception handling in {{processProperties}} to maintain consistency with command-line parsing: if (opt.hasArg()) { if (Util.isEmpty(opt.getValues())) { opt.processValue(value); // Check if value was successfully set if (opt.getValues() == null && !opt.hasOptionalArg()) { throw new MissingArgumentException(opt); } } } Alternatively, catch and re-throw as ParseException: if (opt.hasArg()) { if (Util.isEmpty(opt.getValues())) { try { opt.processValue(value); } catch (final RuntimeException exp) { throw new ParseException("Invalid value for option: " + option + " - " + exp.getMessage()); } // Validate the value was set if (opt.getValues() == null && !opt.hasOptionalArg()) { throw new MissingArgumentException(opt); } } } -- This message was sent by Atlassian Jira (v8.20.10#820010)