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

Better error handling for parseAsync() #1144

Closed
HNicolas opened this issue Jan 7, 2020 · 4 comments
Closed

Better error handling for parseAsync() #1144

HNicolas opened this issue Jan 7, 2020 · 4 comments

Comments

@HNicolas
Copy link

HNicolas commented Jan 7, 2020

Hello,
When using the new method parseAsync() it seems that it is not possible to override the default error handling behavior :

  • calling a command that does not exist, parseAsync() does not throw an error or exit the process, the promise resolve
  • calling a command with wrong parameters (missing required parameter) the process exit with code 1

It should be possible to override those default behaviors in order to catch an error like with the sync parse() method.

@shadowspawn
Copy link
Collaborator

shadowspawn commented Jan 7, 2020

It should be possible to override those default behaviors in order to catch an error like with the sync parse() method.

parseAysnc() calls .parse(), and you override the default behaviours the same way. I am guessing you have not done that, and would see the same error handling behaviours as you describe if you called .parse() instead?

calling a command that does not exist, parseAsync() does not throw an error or exit the process, the promise resolve

Commander sees a command that does not exist as an argument that you don't happen to handle. (Related collection of issues: #1088)

The current approach is to add a custom event listener and there is an example in README:
https://github.com/tj/commander.js#custom-event-listeners

calling a command with wrong parameters (missing required parameter) the process exit with code 1

See .exitOverride(): https://github.com/tj/commander.js#override-exit-handling

@HNicolas
Copy link
Author

HNicolas commented Jan 8, 2020

I didn't know that it was the correct behavior for when calling a command that does not exist.
But there is still a problem when calling parseAsync() with wrong parameters, I do call .exitOverride() but the process still exit without throwing an error or calling the provided callback if any.
Example of code :

    const program = new Command();
    program.command("test <req>")
      .action(async () => {
        // do some async work
      });
    program.exitOverride()
      .parseAsync(process.argv)
      .catch(error => {
        // not reached on invalid command (missing req)
      });

@shadowspawn
Copy link
Collaborator

To get the exitOverride to apply to the subcommand too, define it before adding the command. Then to catch the error I think you need to be in an async context when it is thrown.

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

program
  .exitOverride()
  .command("test <req>")
  .action(async () => {
    // do some async work
  });

async function main() {
  return program.parseAsync(['node', 'my.js', 'test']); // Oops, req missing
}

main().then(() => {
  console.log('main.then');
})
.catch(error => {
  console.log('main.caught');
  console.log(error);
});
$ node index.js 
error: missing required argument 'req'
main.caught
CommanderError: error: missing required argument 'req'
...

@HNicolas
Copy link
Author

HNicolas commented Jan 8, 2020

It works, thank you for your help.

@HNicolas HNicolas closed this as completed Jan 8, 2020
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

No branches or pull requests

2 participants