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