-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[Feature Request] Pass Command instance to argParsers #1968
Description
Since #1915 has been closed, I have been working on a third-party library that would offer similar functionality by means of subclassing.
The most promising approach seems to be to overwrite the .parseArg property of Option and Argument instances whenever it receives a new value, so something like this:
/**
* @param {typeof Option | typeof Argument} Base
*/
function ParseArgMixin(Base) {
return class extends Base {
#originalArgParser = undefined; // argParser provided by library user
#parseArg = (value, previous) => {
// This function is the one
// that will overwrite the argParser provided by library user,
// but it will still call it internally.
};
#overwriteParseArg() {
this.#originalArgParser = this.parseArg;
this.parseArg = this.#parseArg;
}
argParser(fn) {
super.argParser(fn);
this.#overwriteParseArg();
return this;
}
};
}However, there is one problem when it comes to catching errors in promise chains.
I would like to handle such errors in the same manner errors in synchronous argParsers are currently handled, and that involves calling the .error() method on the Command instance if the error turns out to be an InvalidArgumentError. However, that is not possible because neither Option nor Argument instances have access to this method.
That is why I suggest to extend the argParser signature by a third parameter whose value will always be the Command instance in which the argParser was called.
argParser<T>(fn: (value: string, previous: T, command: Command) => T): this;Another reaason why that could come in handy in my scenario is because it would make it possible to only treat promises specially when .parseAsync() has been called, e.g. by reading the _asyncParsing property just like in #1915.
Regular users could also benefit from this change since it would enable them to write reusable argParsers with custom error messages (which they might want to do if they are not satisfied with the default ones for whatever reason). Or they could retrieve the version number via .version() and include it in the error message. Or they could even choose to call .help() instead of .error(). There is a lot that could be done.