enoent.js
 1  'use strict';
 2  
 3  const isWin = process.platform === 'win32';
 4  
 5  function 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  
15  function 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  
38  function verifyENOENT(status, parsed) {
39      if (isWin && status === 1 && !parsed.file) {
40          return notFoundError(parsed.original, 'spawn');
41      }
42  
43      return null;
44  }
45  
46  function verifyENOENTSync(status, parsed) {
47      if (isWin && status === 1 && !parsed.file) {
48          return notFoundError(parsed.original, 'spawnSync');
49      }
50  
51      return null;
52  }
53  
54  module.exports = {
55      hookChildProcess,
56      verifyENOENT,
57      verifyENOENTSync,
58      notFoundError,
59  };