通过IPC通道从生成的subprocess发送错误对象
我启用了父进程和subprocess之间的通信,以发送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的东西工作正常。 但是,如果我挑起一个错误,这是行不通的。 我想将整个错误对象(包含消息和堆栈跟踪)从子项发送给父项。 但是,这似乎不是我发送的错误的一个实例。
进程不共享内存,所以唯一的沟通方式是使用string,对象是JSON序列化的发送和JSONparsing接收。 错误对象默认情况下序列化不好:
JSON.stringify(new Error()) "{}"
此外,JSONparsing对象是无types的,所以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}"
然后自动重build它:
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. } }));
这是我尝试和工作的东西,
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); }
在抛出之前先创build对象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)); } });