Yargs: Make number type act like .choices() for invalid or missing input

Created on 26 Feb 2018  路  2Comments  路  Source: yargs/yargs

Currently for options of type number, if the user provides the option and fails to provide valid input,
the value is returned as either NaN or undefined. _No idea who needs that._ Can we make it act more like .choices() and just implode? Not doing so makes implementing yargs.check() function argument arduous when much is seemingly unnecessary.

binary = path.basename pkg.bin      # From "package.json"
argv = yargs
  .usage('...')
  .options(Abao.options)
  .check((argv) ->
    # Ensure single positional argument present
    if argv._.length < 1
      throw new Error binary + ': must specify path to file'
    else if argv._.length > 1
      throw new Error binary + ': accepts single positional command-line argument'

    ## Validate "timeout" option
    if _.isUndefined argv.timeout
      throw new Error binary + ': option "--timeout" given without a value'
    if _.isNaN argv.timeout
      # Would be better message if it included unparsable user argument value
      throw new Error binary + ': option "--timeout" value could not be parsed as a number'
    if !_.isInteger argv.timeout
      throw new Error binary + ': option "--timeout" value must be scalar integer'
    if argv.timeout < 0
      throw new Error binary + ': option "--timeout" value must be nonnegative'

    #
    # YA four-part stanza like above for EVERY numeric option...
    #

    return true
  )
  .help('help', 'Show usage information and exit')
  .version().describe('version', 'Show version number and exit')
  .argv

Technically, the above requested change only handles the first half of the stanza.
Would need to add two more API methods to handle the rest:

.scalar(key, bool) - if true, only single value accepted (no array); otherwise, false (default).
.range(key, func) - user-provided function to handle range validation

e.g.,

nonnegative = (val) -> val < 0
yargs.range('timeout', nonnegative)

For that matter, how about a sibling .integer(key) method that only accepts integers?

Continuation of now closed #110 discussion...

feature request next-major

Most helpful comment

Currently for options of type number, if the user provides the option and fails to provide valid input,
the value is returned as either NaN or undefined. _No idea who needs that_. Can we make it act more like .choices() and just implode?

This part has definitely bitten me more than once. If I specify that an argument is a number, and the user enters something that is not a number, yargs should immediately let the user know they entered an invalid value. Continuing with NaN like it does now is just a recipe for weird undiagnosable errors down the line.

P.S.
I have no opinion on the rest of the post with the check()/scalar()/range() stuff. They seem like separate issues, to be honest. I only wanted to add support for the part I quoted above.

All 2 comments

Currently for options of type number, if the user provides the option and fails to provide valid input,
the value is returned as either NaN or undefined. _No idea who needs that_. Can we make it act more like .choices() and just implode?

This part has definitely bitten me more than once. If I specify that an argument is a number, and the user enters something that is not a number, yargs should immediately let the user know they entered an invalid value. Continuing with NaN like it does now is just a recipe for weird undiagnosable errors down the line.

P.S.
I have no opinion on the rest of the post with the check()/scalar()/range() stuff. They seem like separate issues, to be honest. I only wanted to add support for the part I quoted above.

This got me as well. Expecting that when I define type: 'number' that the input is validated to actually be a number.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexreg picture alexreg  路  5Comments

atian25 picture atian25  路  4Comments

aorinevo picture aorinevo  路  3Comments

diesal11 picture diesal11  路  3Comments

strugee picture strugee  路  5Comments