简体   繁体   中英

How to catch error from a forked child process?

Node.js v8.11.1

There are two files: parent.js and child.js.

Parent

const { fork } = require('child_process');

const forked = fork('./child');

forked.on('message', (msg) => {
  console.log('Message from child', msg);
  forked.kill();
});

forked.on('error', (err) => {
  console.log('Error from child', err);
});

forked.send({ hello: 'world' });

Child

process.on('message', (msg) => {
  console.log('Message from parent:', msg);
});

try {
  let counter = 0;

  seTimeout(() => {
    process.send({ counter: counter++ });
  }, 1000);
} catch (err) {
  throw new Error('not good: ' + err);
}

There is an intentional typo in the child script - seTimeout . When I execute parent node parent.js , I get:

/media/trex/safe/Development/child.js:12
  throw new Error('not good: ' + err);
  ^

Error: not good: ReferenceError: seTimeout is not defined
    at Object.<anonymous> (/media/trex/safe/Development/siren/sentinl-private/server/lib/actions/report/child.js:12:9)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

The error was not caught by the parent. How to catch the error by the parent?

Update 1

As I see here https://github.com/nodejs/node/issues/15734 this is working as intended. Maybe there is another event to catch errors or something else?

Update 2

Now I can catch an error the following way. But I'm not sure it is the best way to do it.

Parent

const { fork } = require('child_process');

const forked = fork('./child');

forked.on('message', (msg) => {
  if (msg.error) {
    console.error(msg.error);
  } else {
    console.log('Message from child', msg);
  }
  forked.kill();
});

forked.send({ hello: 'world' });

Child

process.on('message', (msg) => {
  console.log('Message from parent:', msg);
});

try {
  let counter = 0;

  seTimeout(() => {
    process.send({ counter: counter++ });
  }, 1000);
} catch (err) {
  process.send({error: err.message});
}

Why not to use the array of the option.stdio ? This array has three elements [subprocess.stdin, subprocess.stdout, subprocess.stderr] , thus you just want to console the errors and not anything else.

Therefore you'd use stdio: ['ignore', 'ignore', 'inherit']

Parent

const { execSync } = require('child_process')

try {
  execSync('node myNodeChildScript.js', { stdio: ['ignore', 'ignore', 'inherit'] })
} catch (err) {
  console.error(Error(err))
  process.exit(1)
}

Child

console.log('Some log') // this will not be output to parent
if (someError()) {
  console.error('There was an error') // this will be output to parent console
  process.exit(1) // exit with error
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM