我启用了父进程和子进程之间的通信,以便按如下方式发送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的工作正常。但如果我挑起错误,它就行不通。我想将整个错误对象(带有消息和堆栈跟踪)从子节点发送到父节点。但它似乎并不是我发送的错误实例。
答案 0 :(得分:4)
进程不共享内存,因此唯一的通信方式是使用字符串,对象在发送时进行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.
}
}));
答案 1 :(得分: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));
}
});