RED.util.encodeObject & TypeError: Converting circular structure to JSON

Hi There,

I just experienced a strange situation whereby my websocket connection to Node-RED dies and I get no more debug messages but Node-RED continues to work. Similar to this question.

How did I manage to do this? Basically this code:

RED.util.encodeObject({
    msg: "execfunc",
    payload: msg.payload,
    topic: msg.topic,
    func: cfg.clientcode,
    nodeid: node.id,
    _msg: msg
})

Here the problem is the msg object which contains a Socket object (the msg object passed out of a http-in node contains a Socket object), in the Node-RED log:

34 Sep 27:29:38 - [warn] Communication send error: TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Socket'
    |     property 'parser' -> object with constructor 'HTTPParser'
    --- property 'socket' closes the circle

This seems to be an error downstream from the encodeObject because that encodeObject is part of a comms publish call:

RED.comms.publish(
    "introspect:client-code-perform",
    RED.util.encodeObject({
       ....
    })
);

That goes over the websocket and the that dies because of the json encoding error.

I fixed this bug by doing a "pre"-Json.Stringify:

// msg object may cause problem if there are circular references, so
// do a pre-stringify before erroring out.
try {
    JSON.stringify(msg)
} catch (e) {
    msg = `[Error in JSON.stringify(msg)]\n${e}\n[End Error]\n`
}

Why do I talk about this? Because this error is very subtle as it occurs somewhere in the RED.comms.publish call even though the encodeObject contains data that won't go over the wire.

I would have expected that the encodeObject would handle this case or have raised an error before my communication websocket dies. And because I don't have my Node-RED log file open, the only thing I noticed was that there was no more debug messages. So it's also very hard to diagnose the cause of no more debug messages.

This happens in the 4.0.2 version, as well as the 3.1.x series.

The mystery deepens: when I use RED.util.encodeObject in a function node, I get the following debug message:

notice that _msg has the value [Circular ~] - so the version of encodeObject in a function node has different handling of the circular error....

Ah, things like socket, res and req objects contain CIRCULAR references and cannot be serialised. This sounds like encodeObject isn't checking for those properties, it should force remove them before dealing with the input.

A bug.

Seems so but whether this is a bug, I'm not quite sure. Since I don't know for what exactly encodeObject should be used for, perhaps sending the results over RED.comms.publish is not an intended use case.

But I doubt that :wink:

Edit: P.S. this difference in APIs reminds me of my question from last week!

In most cases the node-red core nodes watch for those properties and remove them and because you get differing results between the 2 versions of the functions, I would say this is most likely an oversight and therefore a bug. :grinning:

Unfortunately, documentation is rather light:

https://nodered.org/docs/api/modules/v/0.20.0/@node-red_util_util.html#.encodeObject

What I would say is that none of socket, res or req are likely to be useful if moving between runtime and Editor or visa versa. Probably best to get rid of them.

1 Like