Baldhor / Homey-ESPhome-Enhanced

This is an Homey app which adds support for ESPHome devices. ESPHome is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems. More information on their homepage: https://www.esphome.io/
GNU General Public License v3.0
4 stars 3 forks source link

native api client has a circular reference #16

Closed Baldhor closed 10 months ago

Baldhor commented 10 months ago

Describe the bug There are a circular reference inside the native api client library. I have no idea where it is but it's easy to observe when tyring to log the client object through consolre.re:

2023-08-13T18:15:30.527Z [log] [MyApp] ConsoleRe emit error, probably because the log include a circular reference: RangeError: Maximum call stack size exceeded
    at isBinary (/node_modules/socket.io-parser/build/cjs/is-binary.js:22:18)
    at _deconstructPacket (/node_modules/socket.io-parser/build/cjs/binary.js:24:37)
    at _deconstructPacket (/node_modules/socket.io-parser/build/cjs/binary.js:40:32)
    at _deconstructPacket (/node_modules/socket.io-parser/build/cjs/binary.js:40:32)
    at _deconstructPacket (/node_modules/socket.io-parser/build/cjs/binary.js:40:32)
    at _deconstructPacket (/node_modules/socket.io-parser/build/cjs/binary.js:40:32)
    at _deconstructPacket (/node_modules/socket.io-parser/build/cjs/binary.js:40:32)
    at _deconstructPacket (/node_modules/socket.io-parser/build/cjs/binary.js:40:32)
    at _deconstructPacket (/node_modules/socket.io-parser/build/cjs/binary.js:40:32)
    at _deconstructPacket (/node_modules/socket.io-parser/build/cjs/binary.js:40:32)

If I detach the connection from the entities, the circular reference seems solved (however, we don't get the events anymore ...). In the code, I don't see a problem: client -> connection client -> entities -> connection There are no obviously circular reference like client -> connection -> entities -> connection -> ...

To Reproduce Just activate consolre.re and log the native api client.

Expected behavior Circular reference are bad :) No failure of the consolre.re api.

RoadXY commented 10 months ago

Are you sure it doesn't have something to do with "RangeError: Maximum call stack size exceeded" ? I agree having both error messages on 1 sentence is a bit confusing...

Baldhor commented 10 months ago

@RoadXY It's 100% related.

The console.re client use socket.io to send the "objects" the way they are (it's not just strings!). However it cannot handle circular reference. Anyway in a garbage collected environment, circular references should be avoided! So the problem doesn't belong to socket.io.

I just need to find it to solve it :)

Baldhor commented 10 months ago

Solved using this trick:

                const stringifyCircularJSON = obj => {
                    const seen = new WeakSet();
                    return JSON.stringify(obj, (k, v) => {
                        if (v !== null && typeof v === 'object') {
                            if (seen.has(v)) return;
                            seen.add(v);
                        }
                        return v;
                    });
                };

                let obj = JSON.parse(stringifyCircularJSON(arg));

Since I obtain a deep copy, I can then apply filters on it to remove useless or secret data. Currently only "password" are hidden.