As with most Java libraries Airline uses Java exceptions as a way to signal problems. Airline exceptions are unchecked exceptions (which means calling code is not required to handle them) however in order to provide a good user experience you will usually want to handle these. The root type for Airline exception is simply ParseException
but there is a whole hierarchy of more specific exceptions below that:
ParseException
- Base Airline Exception
ParseAliasCircularReferenceException
- Indicates a circular reference while resolving command aliasesParseInvalidRestrictionException
- Indicates that a declared restriction annotation is not validParseOptionConversionException
- Indicates that Airline could not successfully convert the raw string value into the Java type associated with the option/argumentsParseOptionUnexpectedException
- Indicates that an option was used in an unexpected/invalid way e.g. trying to use an option in classic getopt
style that does not have a short formParseRestrictionViolationException
- Indicates that a Restriction was violated
ParseArgumentsIllegalValueException
- Indicates that an arguments value was not in the set of acceptable valuesParseArgumentsMissingException
- Indicates that values for an arguments were expected but not providedParseArgumentsUnexpectedException
- Indicates that unexpected arguments were receivedParseCommandMissingException
- Indicates that the user did not specify a command to execute and there was no suitable default command definedParseCommandUnrecognizedException
- Indicates that an invalid command/group name was specifiedParseOptionGroupException
- Indicates that a restriction that applied over a group of options e.g. @MutuallyExclusiveWith
was violatedParseOptionIllegalValueException
- Indicates that an options value was not in the set of acceptable valuesParseOptionMissingException
- Indicates that a required option was not specifiedParseOptionMissingValueException
- Indicates that an options value was expected but not providedParseOptionOutOfRangeException
- Indicates that an option/arguments value was not within the acceptable range of valuesParseTooManyArgumentsException
- Indicates that too many options/arguments were providedSome aspects of Airline that deal with IO, most notably the Help subsystem will use standard Java IOException
and these are checked exceptions which you should handle appropriately.
As with most things in Airline you have some ability to customise the error control flow. While some things are considered as fatal errors, e.g. missing/invalid metadata annotations, and always throw errors in the actual parsing phase you can control how errors are handled. Error handling is done by the ParserErrorHandler
interface, the desired handler can be defined in your parser configuration via the @Parser
annotations errorHandler
field e.g.
@Parser(errorHandler = CollectAll.class)
The default error handler is FailFast
, this error handler will simply throw the first parsing error encountered i.e. parsing halts immediately on encountering an error.
Sometimes you may wish to collect up all the errors before failing in which case the FailAll
handler will collect and throw either a single exception if only 1 error was encountered or an aggregated exception containing all the errors as suppressed exceptions.
Alternatively you may wish to collect up all the errors and then make an intelligent decision on how to proceed. For example if the user has specified your help option then you probably want to show them your help message regardless of the errors. In this case the CollectAll
handler will allow you to do this.
In order to act intelligently both the Cli
and the SingleCommand
classes provide a parseWithResult(String... args)
method that returns a ParseResult<T>
instance. This can be used to inspect the results of parsing and act appropriately. For example if we wanted to show the error messages and the help output we might do the following:
public static void main(String[] args) {
com.github.rvesse.airline.Cli<ExampleRunnable> cli = new com.github.rvesse.airline.Cli<ExampleRunnable>(ShipItCli.class);
try {
// Parse with a result to allow us to inspect the results of parsing
ParseResult<ExampleRunnable> result = cli.parseWithResult(args);
if (result.wasSuccessful()) {
// Parsed successfully, so just run the command and exit
System.exit(result.getCommand().run());
} else {
// Parsing failed
// Display errors and then the help information
System.err.println(String.format("%d errors encountered:", result.getErrors().size()));
int i = 1;
for (ParseException e : result.getErrors()) {
System.err.println(String.format("Error %d: %s", i, e.getMessage()));
i++;
}
System.err.println();
com.github.rvesse.airline.help.Help.<ExampleRunnable>help(cli.getMetadata(), Arrays.asList(args), System.err);
}
} catch (Exception e) {
// Errors should be being collected so if anything is thrown it is unexpected
System.err.println(String.format("Unexpected error: %s", e.getMessage()));
e.printStackTrace(System.err);
}
// If we got here we are exiting abnormally
System.exit(1);
}
This documentation is itself open source and lives in GitHub under the docs/ directory.
I am not a professional technical writer and as the developer of this software I can often make assumptions of
knowledge that you as a user reading this may not have. Improvements to the documentation are always welcome, if you
have suggestions for the documentation please submit pull requests to the main
branch.