| 'use strict'; |
| |
| const isWin = process.platform === 'win32'; |
| |
| function notFoundError(original, syscall) { |
| return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { |
| code: 'ENOENT', |
| errno: 'ENOENT', |
| syscall: `${syscall} ${original.command}`, |
| path: original.command, |
| spawnargs: original.args, |
| }); |
| } |
| |
| function hookChildProcess(cp, parsed) { |
| if (!isWin) { |
| return; |
| } |
| |
| const originalEmit = cp.emit; |
| |
| cp.emit = function (name, arg1) { |
| // If emitting "exit" event and exit code is 1, we need to check if |
| // the command exists and emit an "error" instead |
| // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 |
| if (name === 'exit') { |
| const err = verifyENOENT(arg1, parsed, 'spawn'); |
| |
| if (err) { |
| return originalEmit.call(cp, 'error', err); |
| } |
| } |
| |
| return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params |
| }; |
| } |
| |
| function verifyENOENT(status, parsed) { |
| if (isWin && status === 1 && !parsed.file) { |
| return notFoundError(parsed.original, 'spawn'); |
| } |
| |
| return null; |
| } |
| |
| function verifyENOENTSync(status, parsed) { |
| if (isWin && status === 1 && !parsed.file) { |
| return notFoundError(parsed.original, 'spawnSync'); |
| } |
| |
| return null; |
| } |
| |
| module.exports = { |
| hookChildProcess, |
| verifyENOENT, |
| verifyENOENTSync, |
| notFoundError, |
| }; |