Commander.js: Triage: Exit

Created on 1 Apr 2019  路  7Comments  路  Source: tj/commander.js

Commander calls exit under various circumstances, such as after displaying an error or the help. This is pretty convenient for the caller of a one-shot parse in a CLI, but is a problem when Commander is being used as part of a long running program or if caller wants more control over the failure handling.

Issues:

  • #188 optional exit value for Help. (feature request)
  • #435 process.exit(64)
  • #443 Explicitly return when an error occurs
  • #575 Make calls to process.exit() overridable
  • #934 Parse multiple commands without exiting the process

Pull Requests:

  • #436 Add support for exit codes.
  • #444 Explicitly return from error methods
  • #576 Make process.exit() injectable.

Most helpful comment

I am experimenting with a routine to optionally replace calls to process.exit. Since the most likely implementation is to throw, it is passed an Error ready to throw. e.g.

program.exitOverride((err) => { throw err; });

The custom error has properties for exitCode, code, and message. For example, the --version handling creates an error like this:

CommanderError(0, 'commander.version', this._version)

I'm currently just replacing the call to process.exit and not changing where or how the preceding messages are displayed. One thing at a time.

All 7 comments

Yes, please simply throw errors. The outer program can catch the errors and handle them properly.

I think being able to opt-in to using a throw makes good sense. But I think it is a bit untidy for default handling of expected errors with the source line number and code? Compared with just a message intended for humans.

a bit untidy for default handling

To be backward compatible, we can add an option to:
Command.prototype.parse = function(argv)

like this:
Command.prototype.parse = function(argv, exitOnError = true)

I am experimenting with a routine to optionally replace calls to process.exit. Since the most likely implementation is to throw, it is passed an Error ready to throw. e.g.

program.exitOverride((err) => { throw err; });

The custom error has properties for exitCode, code, and message. For example, the --version handling creates an error like this:

CommanderError(0, 'commander.version', this._version)

I'm currently just replacing the call to process.exit and not changing where or how the preceding messages are displayed. One thing at a time.

There are improvements on the develop branch for the next release (#1040).

v4.0.0-0 prerelease published: #1067

v4.0.0 has been released. It does not cover all the exit related issues found in triage, but addresses the most common issue of the unconditional call to exit.

Feel free to open a new issue if still issues, with new information and renewed interest.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

oknoorap picture oknoorap  路  4Comments

mathiasbynens picture mathiasbynens  路  3Comments

cmoulliard picture cmoulliard  路  4Comments

RoXioTD picture RoXioTD  路  4Comments

FerencH picture FerencH  路  4Comments