1'use strict'; 2 3const isWin = process.platform === 'win32'; 4 5function notFoundError(original, syscall) { 6 return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { 7 code: 'ENOENT', 8 errno: 'ENOENT', 9 syscall: `${syscall} ${original.command}`, 10 path: original.command, 11 spawnargs: original.args, 12 }); 13} 14 15function hookChildProcess(cp, parsed) { 16 if (!isWin) { 17 return; 18 } 19 20 const originalEmit = cp.emit; 21 22 cp.emit = function (name, arg1) { 23 // If emitting "exit" event and exit code is 1, we need to check if 24 // the command exists and emit an "error" instead 25 // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 26 if (name === 'exit') { 27 const err = verifyENOENT(arg1, parsed, 'spawn'); 28 29 if (err) { 30 return originalEmit.call(cp, 'error', err); 31 } 32 } 33 34 return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params 35 }; 36} 37 38function verifyENOENT(status, parsed) { 39 if (isWin && status === 1 && !parsed.file) { 40 return notFoundError(parsed.original, 'spawn'); 41 } 42 43 return null; 44} 45 46function verifyENOENTSync(status, parsed) { 47 if (isWin && status === 1 && !parsed.file) { 48 return notFoundError(parsed.original, 'spawnSync'); 49 } 50 51 return null; 52} 53 54module.exports = { 55 hookChildProcess, 56 verifyENOENT, 57 verifyENOENTSync, 58 notFoundError, 59}; 60