【问题标题】:Sending an Error Object from a spawned child-process over an IPC-channel通过 IPC 通道从衍生的子进程发送错误对象
【发布时间】:2015-03-03 23:37:34
【问题描述】:

为了发送 JSON,我启用了父子进程之间的通信,如下所示:

孩子:

try {  
  var price1 = parseInt(process.argv[2]);
  if (!price1) {
     throw new Error('Price in calculations.js undefined');
  }
  var result = {
    'timeStamp' : Date(),
    'prices' : { 'player1' : price1, 'player2' : 666}
  };
  process.send(result);
} catch (e) {
  // In case of an error, I get here as expected.
  process.send(e);
}

家长:

var spawn = require('child_process').spawn;
var child = spawn('node', ['calculations.js', 333],  {stdio: [null,null,'pipe','ipc']});
child.on('message', function(data) {    
  if (data instanceof Error) {
    // In case of an error, this is never reached.
  } else {
    // do sthing with JSON object.
  }
});

JSON 的东西工作正常。但如果我引发错误,它就不起作用。我想将整个错误对象(带有消息和堆栈跟踪)从子级发送到父级。但这似乎不是我发送的错误实例。

【问题讨论】:

  • provoke哪个错误?
  • 我更新了帖子。我只是设置了 process.argv[3] 然后抛出我的自定义错误。
  • 你正在用 3 个参数生成进程,为什么会抛出错误
  • 这与在 shell 中执行 'node computed.js 333' 相同。 process.argv[0] 将是“节点”,process.argv[1] 是计算.js 的路径,而 process.argv[2] 是 333。process.argv[4] 是未定义的,这就是我抛出错误的原因.

标签: javascript node.js inter-process-communicat


【解决方案1】:

这是我尝试过并且有效的方法,

var Error=function(mes){
    this.message=mes;
};

try {  
  var price1 = parseInt(process.argv[4]);
 if (!price1) {
     throw new Error('Price in calculations.js undefined');
 }
  var result = {
    'timeStamp' : Date(),
    'prices' : { 'player1' : price1, 'player2' : 666}
  };  console.log("inside try");
  process.send(result);
} catch (e) {
  // In case of an error, I get here as expected.
  console.log("inside catch");
  process.send(e);
}

在抛出之前先创建对象Error,否则它只是传递一个不是instanceof Error的空对象。

还有父母

var child = require('child_process').fork(__dirname + '/SO2.js', [333],  {stdio: [null,null,'pipe','ipc']});

child.on('message', function(data) {
  if(data.timeStamp){
    console.log("result received ");
  } 
  else{
    // do sthing with JSON object.
    console.log("user defined error messege"+data.message + JSON.stringify(data));
  }
});

【讨论】:

  • 嗯,但在这种情况下,我无法获得堆栈。它还打印出“用户定义的错误messegemes {“message”:“mes”}”而不是我给出的错误消息
  • 哦对不起,应该是var Error=function(mes){ this.message=mes; };
  • 啊,当然,像这样它可以与消息一起使用。您知道如何获取堆栈跟踪吗?
【解决方案2】:

进程不共享内存,因此唯一的通信方式是使用字符串,对象在发送时序列化 JSON,在接收时解析回 JSON。默认情况下,错误对象不能很好地序列化:

JSON.stringify(new Error())
"{}"

另外,JSON 解析的对象是无类型的,因此 instanceof 无法工作。

您可以为错误对象制作序列化挂钩:

Error.prototype.toJSON = function() {
    var ret = {
        name: this.name,
        message: this.message,
        stack: this.stack,
        __error__: true
    };
    // Add any custom properties such as .code in file-system errors
    Object.keys(this).forEach(function(key) {
        if (!ret[key]) {
            ret[key] = this[key];
        }
    }, this);
    return ret;
};

在方法定义错误对象序列化之后更好:

 JSON.stringify(new Error())

"{"name":"Error","message":"","stack":"Error\n    at <anonymous>:2:16\n    at Object.InjectedScript._evaluateOn (<anonymous>:762:137)\n    at Object.InjectedScript._evaluateAndWrap (<anonymous>:695:34)\n    at Object.InjectedScript.evaluate (<anonymous>:609:21)","__error__":true}"

然后自动重构:

function getMessageReceiver(fn) {
    return function(data) {
        var result = data;
        if (data && data.__error__) {
            result = new Error();
            result.message = data.message;
            result.stack = data.stack;
            result.name = data.name;
            Object.keys(data).forEach(function(key) {
                if (!result[key]) {
                    result[key] = data[key];
                }
            });
        }
        return fn.call(this, result);
    }
}

最后:

child.on('message', getMessageReceiver(function(data) {    
  if (data instanceof Error) {
    console.log(data.stack); // Stack is from child process
  } else {
    // do sthing with JSON object.
  }
}));

【讨论】:

  • 另一个问题:我试图通过管道从子级的标准输出向父级发送 JSON 来模仿 ipc 通道:子级中的 console.log(JSON.stringify(result)); 和父级中的 JSON.parse(data);。但它总是会抛出一个SyntaxError: Unexpected token u at Object.parse (native)。这个 ipc-channel 有什么不同?到底是什么?
  • @Kiechlus data 不是 JSON 字符串,也许试试 console.log(data) 看看它是什么,很可能是 "undefined"
猜你喜欢
  • 2016-10-07
  • 1970-01-01
  • 2014-09-25
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多