Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom error messages for option argument coercion failures #1392

Merged

Conversation

shadowspawn
Copy link
Collaborator

@shadowspawn shadowspawn commented Nov 7, 2020

Pull Request

Problem

It can be tricky to do nice error messages for custom option processing failures since the option name is not available.

Issues: #1207 #518 (comment)

Solution

We already added a custom exception to process the error message for the new .choices() routine. This takes that a little further to make the exception usable by custom option processing routines and not just Option methods.

For example:

const commander = require('commander');
const program = commander.program;

program
  .option('-p, --port <port>', 'port number', (arg) => {
    const portNumber = parseInt(arg);
    if (isNaN(portNumber)) {
      throw new InvalidOptionArgumentError('Must be a number.');
    }
    return portNumber;
  });

program.parse();
options % node throw.js -p       
error: option '-p, --port <port>' argument missing
options % node throw.js -p 123   
options % node throw.js -p Madrid
error: option '-p, --port <port>' argument 'Madrid' is invalid. Must be a number.

Release Note

  • Added: throwInvalidOptionArgumentError from custom option processing for detailed error message.

To Do

  • README
  • tests
  • example
  • TypeScript

@shadowspawn
Copy link
Collaborator Author

FYI: @lydell @vonagam

@lydell
Copy link

lydell commented Nov 7, 2020

Looks great! Exactly what I need. Though maybe a little more low-level than I anticipated. [Edit: refers to older version of code, with this comment leading to changes.]

Two thoughts:

  • I think this should be mentioned in the readme docs.

  • In my project, I would define the following helper function:

function invalidArgument(message) {
  return new commander.CommanderError(1, 'commander.optionArgumentRejected', message);
}

// Later, somewhere:
throw invalidArgument('Must be a number.')

Do we want a shorter way to do this out of the box? I’m thinking you can’t customize the exit code for other errors, such as “missing option”, right? So maybe we don’t need that ability here. Is there a use case for using any other code than 'commander.optionArgumentRejected'?

@shadowspawn
Copy link
Collaborator Author

Though maybe a little more low-level than I anticipated.

Fair comment, and good feedback thanks. I was trying a quick repurpose of the existing internals. 😊

@shadowspawn
Copy link
Collaborator Author

Added somewhat higher level wrapper:

  .option('-p, --port <port>', 'port number', (arg) => {
    const portNumber = parseInt(arg);
    if (isNaN(portNumber)) {
      throw new commander.InvalidOptionArgumentError('Must be a number.');
    }
    return portNumber;
  })

@lydell
Copy link

lydell commented Nov 9, 2020

Looks good!

@shadowspawn shadowspawn marked this pull request as ready for review November 18, 2020 10:15
@shadowspawn
Copy link
Collaborator Author

Finished missing pieces, ready for review.

Copy link
Collaborator

@abetomo abetomo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate it.

@shadowspawn shadowspawn added the pending release Merged into a branch for a future release, but not released yet label Nov 25, 2020
@shadowspawn shadowspawn added this to the v7.0.0 milestone Nov 25, 2020
@shadowspawn shadowspawn merged commit 689d7a0 into tj:release/7.x Nov 25, 2020
@shadowspawn shadowspawn deleted the feature/throw-invalid-option-argument branch November 25, 2020 06:43
@shadowspawn shadowspawn removed the pending release Merged into a branch for a future release, but not released yet label Jan 16, 2021
@shadowspawn shadowspawn mentioned this pull request May 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants