【问题标题】:How to catch error from a forked child process?如何从分叉的子进程中捕获错误?
【发布时间】:2020-02-17 21:45:52
【问题描述】:

Node.js v8.11.1

有两个文件:parent.js 和 child.js。

父母

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' });

孩子

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);
}

子脚本中有一个故意的拼写错误 - seTimeout。当我执行父 node parent.js 时,我得到:

/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

错误未被父级捕获。如何捕获父级的错误?

更新 1

正如我在这里看到的https://github.com/nodejs/node/issues/15734,这正在按预期工作。也许还有另一个事件来捕获错误或其他什么?

更新 2

现在我可以通过以下方式捕获错误。但我不确定这是不是最好的方法。

父母

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' });

孩子

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});
}

【问题讨论】:

  • @marekful,这是故意的,抛出一个错误
  • 子进程就是这样工作的。如果您想要一个真正的流程,您可以听取流程输出,这就是您所得到的。你必须设计你的父母,以便它可以检查错误的文本,并做“某事”。
  • @Mike'Pomax'Kamermans 你的意思是我唯一的选择是像上面的“更新 2”示例中那样做吗?
  • 正确。 forkspawn 相同,只是它专门用于生成新的节点进程,因此您可以使用标准 i/o 接口。

标签: node.js child-process


【解决方案1】:

为什么不使用option.stdio的数组呢?该数组包含三个元素[subprocess.stdin, subprocess.stdout, subprocess.stderr],因此您只想控制错误而不是其他任何内容。

因此你会使用stdio: ['ignore', 'ignore', 'inherit']

家长

const { execSync } = require('child_process')

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

孩子

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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-22
    • 2011-08-04
    • 2020-08-18
    • 2022-01-05
    • 1970-01-01
    • 2012-08-24
    • 2012-03-16
    相关资源
    最近更新 更多