-
-
Notifications
You must be signed in to change notification settings - Fork 240
Remove faulty emulated ENOENT error on Windows #447
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
Remove faulty emulated ENOENT error on Windows #447
Conversation
test/error.js
Outdated
| const {originalMessage} = await t.throwsAsync(execa('wrong command')); | ||
| t.is(originalMessage, 'spawn wrong command ENOENT'); | ||
| const {originalMessage} = await t.throwsAsync(execa('noop', {cwd: 1})); | ||
| t.regex(originalMessage, /The "options.cwd" property must be of type string. Received type number/); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assertion might not need a regular expression.
| t.regex(originalMessage, /The "options.cwd" property must be of type string. Received type number/); | |
| t.true(originalMessage.startsWith('The "options.cwd" property must be of type string')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed as suggested
test/error.js
Outdated
| if (process.platform !== 'win32') { | ||
| test('error.code is defined on failure if applicable', async t => { | ||
| const {code} = await t.throwsAsync(execa('invalid')); | ||
| t.is(code, 'ENOENT'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There might be ways to fix this test in a way that works on Windows as well.
We need to find an error.code that is cross-platform.
https://github.com/nodejs/node/blob/master/lib/child_process.js#L49-L55
The following might work:
test('error.code is defined on failure if applicable', async t => {
const {code} = await t.throwsAsync(execa(''));
t.is(code, 'ERR_INVALID_ARG_VALUE');
});There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, using an empty command on Windows doesn't generate ERR_INVALID_ARG_VALUE. There aren't many errors thrown consistently across both POSIX & Windows and also across multiple Node versions. The one I found that seems to work is giving an incorrect type for cwd. So I used that again here in the updated version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That works 👍
ehmicky
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @mterrel!
When it comes to detecting ENOENT by looking at the error message, I do agree that it might not be right to make that logic work only for users with English locales. Not only wouldn't it be fair to non-English speakers, but it might confuse users would get very different behaviors between machines and might not realize this is due to the locale.
dcde090 to
469d76b
Compare
ehmicky
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good to me. Thanks @mterrel!
@sindresorhus What do you think?
Old behavior
Prior to this PR,
execaon Windows would emulate behavior seen on POSIX platforms where attempting to run a non-existent command would throw an error that hadcodeset toENOENT. However, this emulation worked incorrectly for many common cases (fixes #446 and moxystudio/node-cross-spawn#104), especially when theshelloption is set to a truthy value.New behavior
There is no obvious way to fix the emulation of
ENOENTon Windows in a reasonable way, so this PR removes it. That means thatexecawill no longer throwENOENTon Windows, but still will on POSIX platforms.After this PR is merged, when
execais given a non-existent command to run on Windows,execawill have the default Node.jsspawnbehavior of throwing an error that hasexitCodeset to1and any error message given by Windows will appear in thestderroutput/stream.Detecting "command not found" on Windows
On English versions of Windows, the error message given by the OS looks similar to this:
However, this message will likely be translated on non-English versions of Windows.
Additional info
Prior to this PR, there were two failing test cases on Windows. Removing the faulty
ENOENTemulation actually fixed those two test cases, but caused two new ones to break. I fixed both by inducing a different error.