commander.js: How to detect an unsupported command?

I have a CLI application that uses commander.js and defines two commands, foo and bar. Since I am using git-style commands, basically my main file looks like this:

program
  .command('foo', 'does something')
  .command('bar', 'does something else')
  .parse(process.argv);

if (process.argv.length === 2) {
  program.help();
}

This works if I call my app without any arguments (then the help is shown, as intended), and it works if I call it with foo or bar as commands.

What does not work is if I specify a non-existing command. In this case, simply nothing happens at all:

$ myapp baz

How can I catch this case? I read that you may use

program.on('*', function () {
  // ...
});

and basically this works, but this executes not only for unknown commands, but for any command. In the same way, specifying a wildcard command does not work either: If I add

program.command('*').action(function () { ... });

this catches unknown commands (which is exactly what I want), but now if you run the app with --help it lists a * command (which is obviously not what I want).

So, to cut a long story short: How do I deal correctly with unknown commands?

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 16

Commits related to this issue

Most upvoted comments

My $0.02 - by default commander.js should sanitize commands and automatically show usage and exit if an unsupported command is used (it doesn’t currently).

For those coming to this issue - the @goloroden solution does not work now. But there is official way mentioned in README:

// error on unknown commands
program.on('command:*', function () {
  console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
  process.exit(1);
});

I hit this same problem but I couldn’t use @goloroden suggestion because I wasn’t using git like commands. Instead I created a executed variable that is false and I make it true if a command executes. Then I just check against it to print the help message:

var executed = false;

program
  .command('foo')
  .action(foo);

program.parse(process.argv);

if (!executed) {
    program.help();
}

function foo() {
    executed = true;
    // ...
}

So, I finally ended up with this:

program
  .version(...)
  .command(...)
  .on('*', function (command) {
    this.commands.some(function (command) {
      return command._name === argv[0];
    }) || this.help();
  })
  parse(...);

This does the job perfectly for me 😃