ENT-1872 - Better cmdline failure msgs for Doorman

When the config file specified doesn't exist, a stacktrace is dum
ped to stdout rather than just printing a nice error message. Same
for specifying a stupid mode.

The nice fix would be if the cmdline parseing library exposed the error
states from Converters properly. Alas, what it actually does is catch
the exception you'd like and throws a very generic exception.

So, catch and rethrow with a better error message and don't dump the
stack (i.e. exit rather than rethrow)
This commit is contained in:
Katelyn Baker 2018-05-10 14:21:18 +01:00
parent 1c2d6d8100
commit d290fd3d6d
4 changed files with 38 additions and 5 deletions

View File

@ -81,7 +81,7 @@ dependencies {
compile "org.glassfish.jersey.containers:jersey-container-jetty-http:${jersey_version}"
// JOpt: for command line flags.
compile "net.sf.jopt-simple:jopt-simple:5.0.2"
compile "net.sf.jopt-simple:jopt-simple:5.0.4"
// TypeSafe Config: for simple and human friendly config files.
compile "com.typesafe:config:$typesafe_config_version"

View File

@ -26,11 +26,26 @@ abstract class ArgsParser<out T : Any> {
}
throw e
}
if (optionSet.has(helpOption)) {
printHelpOn?.let(optionParser::printHelpOn)
exitProcess(0)
}
return parse(optionSet)
return try {
parse(optionSet)
} catch (e: RuntimeException) {
// we handle errors' from the parsing of the command line arguments as a runtime
// exception because the joptsimple library is overly helpful and doesn't expose
// error exceptions in a way that makes reporting the message out to the user
// possible. Thus, that library is re-throwing those exceptions as simple
// runtime exceptions with a modified cause to preserve the error location
printHelpOn?.let {
it.println("ERROR: ${e.message ?: "Unable to parse arguments."}")
exitProcess(-1)
}
throw e
}
}
protected abstract fun parse(optionSet: OptionSet): T

View File

@ -1,7 +1,9 @@
package com.r3.corda.networkmanage.doorman
//import joptsimple.OptionArgumentConversionException
import com.google.common.primitives.Booleans
import com.r3.corda.networkmanage.common.utils.ArgsParser
import joptsimple.OptionException
import joptsimple.OptionSet
import joptsimple.util.EnumConverter
import joptsimple.util.PathConverter
@ -33,8 +35,24 @@ class DoormanArgsParser : ArgsParser<DoormanCmdLineOptions>() {
.withRequiredArg()
override fun parse(optionSet: OptionSet): DoormanCmdLineOptions {
val configFile = optionSet.valueOf(configFileArg)
val mode = optionSet.valueOf(modeArg)
val configFile = try {
optionSet.valueOf(configFileArg)
} catch (e: OptionException) {
throw RuntimeException("Specified config file doesn't exist").apply {
initCause(e.cause)
}
}
val mode = try {
optionSet.valueOf(modeArg)
} catch (e: OptionException) {
throw RuntimeException(
"Unknown mode specified, valid options are [${Mode.values().joinToString(", ")}]"
).apply {
initCause(e.cause)
}
}
val setNetworkParametersFile = optionSet.valueOf(setNetworkParametersArg)
val flagDay = optionSet.has(flagDayArg)
val cancelUpdate = optionSet.has(cancelUpdateArg)

View File

@ -30,7 +30,7 @@ fun main(args: Array<String>) {
}
initialiseSerialization()
val cmdLineOptions = DoormanArgsParser().parseOrExit(*args)
val cmdLineOptions = DoormanArgsParser().parseOrExit(*args, printHelpOn = System.err)
val config = parseConfig<NetworkManagementServerConfig>(cmdLineOptions.configFile)