1'use strict'; 2 3var isWin = process.platform === 'win32'; 4var resolveCommand = require('./util/resolveCommand'); 5 6var isNode10 = process.version.indexOf('v0.10.') === 0; 7 8function notFoundError(command, syscall) { 9 var err; 10 11 err = new Error(syscall + ' ' + command + ' ENOENT'); 12 err.code = err.errno = 'ENOENT'; 13 err.syscall = syscall + ' ' + command; 14 15 return err; 16} 17 18function hookChildProcess(cp, parsed) { 19 var originalEmit; 20 21 if (!isWin) { 22 return; 23 } 24 25 originalEmit = cp.emit; 26 cp.emit = function (name, arg1) { 27 var err; 28 29 // If emitting "exit" event and exit code is 1, we need to check if 30 // the command exists and emit an "error" instead 31 // See: https://github.com/IndigoUnited/node-cross-spawn/issues/16 32 if (name === 'exit') { 33 err = verifyENOENT(arg1, parsed, 'spawn'); 34 35 if (err) { 36 return originalEmit.call(cp, 'error', err); 37 } 38 } 39 40 return originalEmit.apply(cp, arguments); 41 }; 42} 43 44function verifyENOENT(status, parsed) { 45 if (isWin && status === 1 && !parsed.file) { 46 return notFoundError(parsed.original, 'spawn'); 47 } 48 49 return null; 50} 51 52function verifyENOENTSync(status, parsed) { 53 if (isWin && status === 1 && !parsed.file) { 54 return notFoundError(parsed.original, 'spawnSync'); 55 } 56 57 // If we are in node 10, then we are using spawn-sync; if it exited 58 // with -1 it probably means that the command does not exist 59 if (isNode10 && status === -1) { 60 parsed.file = isWin ? parsed.file : resolveCommand(parsed.original); 61 62 if (!parsed.file) { 63 return notFoundError(parsed.original, 'spawnSync'); 64 } 65 } 66 67 return null; 68} 69 70module.exports.hookChildProcess = hookChildProcess; 71module.exports.verifyENOENT = verifyENOENT; 72module.exports.verifyENOENTSync = verifyENOENTSync; 73module.exports.notFoundError = notFoundError; 74