0

This is very interesting! What's happening?

  • Master process is started
  • Master forks a new process (also called a worker)
  • Master also activates a listener on itself, so that it comes to know when a worker is online. (As soon as a worker is online, master will send her a greeting message)
  • Worker is started
  • Worker registers a listener on herself. So when a message is sent by the master to the worker, it is received by her.
  • As soon as the greeting is received by the worker it calls some routine but encounters an error. The worker wants to report the complete error object reported by the routine she just called.
  • The worker wraps the error object in an object and also adds some new keys and uses the send to report back to master.
  • Master is listening to the worker and receives the message but doesn't find the error object that was sent by the worker!

This was the end of the story.

The problem is described in the last point. The error object is not received by the master. What could be the reason? The worker has the error object intact just before sending it to the master.

Here is the code for the description above:

const cluster = require('cluster');
const Promise = require('bluebird');

if (cluster.isMaster) {

    console.log(`Master process is running`);
    let worker = cluster.fork(); // START A WORKER

    worker.on('message', (message) => { // LISTEN TO WORKER
        console.log(`Received from worker: ${message}`);
    });

    cluster.on('online', (worker) => { // LISTEN TO WHEN WORKER IS ONLINE
        worker.send('Hello worker'); // SEND HER A MESSAGE
    });
} else {
    process.on('message', async (message) => { // LISTEN TO HER MASTER
        try {
            let response = await calculate();
            process.send({
                status: true,
                trace: null,
                message: 'ok'
            });
        } catch (err) {
            process.send({
                status: false,
                trace: err, // ERR WAS HERE, BUT DOESN'T REACH MASTER!
                message: err.message
            });
        }
    });
}

function calculate() {
    try {
        throw new Error('This will take forever to compute');
    } catch (err) {
        return Promise.reject(err);
    }
}

If you attempt to run the above code, this will be the output:

Master process is running
Received from worker: {"status":false,"trace":{},"message":"This will take forever to compute"}

As we see, the trace is empty!

Suhail Gupta
  • 22,386
  • 64
  • 200
  • 328
  • 2
    [Is it not possible to stringify an Error using JSON.stringify?](https://stackoverflow.com/questions/18391212/is-it-not-possible-to-stringify-an-error-using-json-stringify) – Alex Blex Sep 07 '17 at 13:56
  • https://stackoverflow.com/questions/32941243/node-js-console-logobject-prints-empty-object – noel zubin Sep 07 '17 at 14:10
  • https://stackoverflow.com/questions/17893718/what-does-enumerable-mean – noel zubin Sep 07 '17 at 14:16

1 Answers1

1

As per API doc, for the process.send() method:

This function uses JSON.stringify() internally to serialize the message

So,

const err = new Error('Message');
console.log(JSON.stringify(err)); // => {}

What you maybe want to do is:

process.send({
    status: false,
    trace: err.stack,
    message: err.message
});
edin-m
  • 3,021
  • 3
  • 17
  • 27