I enabled communication between parent and child process in order to send JSON as follows:
Child:
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);
}
Parent:
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.
}
});
The JSON thing works fine. But if I provoke an error, it doesn't work. I want to send the entire error-object (with message and stack-trace) from child to parent. But it doesn't seem to be an instance of error what I am sending.
The child_process. spawn() method launches a new process with a given command. This method returns streams (stdout & stderr) and it is generally used when the process returns large amount of data. Syntax: child_process.
For example, here's code to spawn a new process that will execute the pwd command. const { spawn } = require('child_process'); const child = spawn('pwd');
The node:child_process module provides the ability to spawn subprocesses in a manner that is similar, but not identical, to popen(3) . This capability is primarily provided by the child_process.
A child process is a process created by a parent process in operating system using a fork() system call. A child process may also be called a subprocess or a subtask. A child process is created as its parent process's copy and inherits most of its attributes.
Processes don't share memory so the only way to communicate is with strings, objects are JSON serialized on send and JSON parsed back on receive. Error objects don't serialize well by default:
JSON.stringify(new Error())
"{}"
Also, JSON parsed object is untyped so instanceof cannot work.
You can make serialization hook for errors objects:
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;
};
After that method definition error objects serialize better:
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}"
Then reconstruct it automatically:
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);
}
}
And finally:
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.
}
}));
This is something I tried and works,
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);
}
First create object Error
before throwing it, otherwise it just pass an empty object which is not instanceof Error
.
And the parent
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));
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With