0

Background: My nodejs application rely on a child process to keep running. When the child process close, the application should end immediatelly after calling some clean-up function.

What I have done so far: I placed everything inside a try-catch block, even the child process's close event (on('close'). Then I throw a new Error inside that event. But it doesn't work as expected.

The code:

const kill = require('tree-kill');
const delay = require('delay');

const main = (async () => {
    try {
        let ps = await require('child_process')
            .spawn(
                'file.exe',
                [
                    '-v'
                ]);

        ps.on('close', async (code) => {
            // await function();
            throw new Error(`Process exited with code ${code}`);
        });

        await delay(1000 * 5);
        console.log('Lengthy process 1')

        kill(ps.pid);

        await delay(1000 * 5);
        console.log('Lengthy process 2 - Should not run')
    }
    catch (e) {
        console.log('Reach catch block');
        console.log(e);
        throw e;
    }
    finally {
        console.log('Reach finally block');
        // Call some clean-up function here
        process.exit(0);
    }
});

main();

The output:

PS D:\apps> node .\main.js
Lengthy process 1
(node:6900) UnhandledPromiseRejectionWarning: Error: Process exited with code 1
    at ChildProcess.<anonymous> (D:\apps\main.js:20:19)
    at ChildProcess.emit (events.js:310:20)
    at maybeClose (internal/child_process.js:1021:16)
    at Socket.<anonymous> (internal/child_process.js:443:11)
    at Socket.emit (events.js:310:20)
    at Pipe.<anonymous> (net.js:672:12)
(node:6900) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:6900) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Lengthy process 2 - Should not run
Reach finally block

Question: How to correctly handle child_process close event on try catch block?

Đức Nguyễn
  • 606
  • 3
  • 9
  • 19
  • Don't use an `async` function if you want the exception to crash your process - otherwise you "only" get an unhandled rejection (which is planned to crash the process as we well, but node isn't going forward with that). Alternatively to throwing, just call `process.exit()`. – Bergi Apr 19 '20 at 19:22
  • Actually I must call some cleanup functions before process exit, that is why I dont use process.exit() in the close event. But thank you, I edited the question. – Đức Nguyễn Apr 19 '20 at 19:27
  • Ok, so if you want to follow through with your `async`/`await` code, you need to properly promisify the `ps` object and await *that*. See the duplicate for constructing a promise that waits for the `exit`/`close` event(s) and rejects. – Bergi Apr 19 '20 at 19:37

0 Answers0