node-red-dashboard icon indicating copy to clipboard operation
node-red-dashboard copied to clipboard

Removing ui-control node instance crash

Open 78wesley opened this issue 1 year ago • 3 comments

Current Behavior

When I remove the ui-control node and click on deploy the instance crash.

The error log that I got is this:

7/10/2024 4:37:17 PM  []        10 Jul 14:37:17 - [red] Uncaught Exception:
7/10/2024 4:37:17 PM  [error]   TypeError: Cannot read properties of null (reading 'send')
    at disconnect (/data/node_modules/@flowfuse/node-red-dashboard/nodes/widgets/ui_control.js:172:31)
    at Socket.emit (node:events:531:35)
    at Socket.emit (node:domain:488:12)
    at Socket.emitReserved (/data/node_modules/socket.io/dist/typed-events.js:56:22)
    at Socket._onclose (/data/node_modules/socket.io/dist/socket.js:561:14)
    at Client.onclose (/data/node_modules/socket.io/dist/client.js:247:20)
    at Socket.emit (node:events:531:35)
    at Socket.emit (node:domain:488:12)
    at Socket.onClose (/data/node_modules/engine.io/build/socket.js:304:18)
    at Object.onceWrapper (node:events:633:28)

Expected Behavior

When I click on deploy it shouldn't crash.

Steps To Reproduce

  1. Place a ui-control node and select your path.
  2. Click on Deploy
  3. Remove the ui-control node
  4. Click on Deploy
  5. Crashed

Environment

  • Dashboard version: 1.12.4
  • Node-RED version: 4.0.2
  • Node.js version: 20.15.0
  • npm version:
  • Platform/OS: Flow Fuse Small Instance
  • Browser: Brave Version 1.67.123 Chromium: 126.0.6478.126 (Official Build) (64-bit)

Have you provided an initial effort estimate for this issue?

I have provided an initial effort estimate

78wesley avatar Jul 10 '24 14:07 78wesley

Are you doing a "Full Deploy" or "Partial Deploy" here? I suspect we may have an issue with the latter, but the former would surprise me

joepavitt avatar Jul 11 '24 08:07 joepavitt

Are you doing a "Full Deploy" or "Partial Deploy" here? I suspect we may have an issue with the latter, but the former would surprise me

I deployed it with Modified Flows.

78wesley avatar Jul 11 '24 10:07 78wesley

Thanks for confirming - the quick "fix" is to do a Full Deploy - but there is an underlying bug you've found with partial deploys, so thanks for reporting!

joepavitt avatar Jul 11 '24 12:07 joepavitt

I hit this today while testing a PR.

  1. moved a gauge from 2nd place to 1st place
  2. deployed (nodes type deploy)
    30 Jun 09:08:13 - [red] Uncaught Exception:
    30 Jun 09:08:13 - [error] TypeError: Cannot read properties of null (reading 'send')
        at disconnect (C:\Users\sdmcl\repos\github\node-red-dashboard\nodes\widgets\ui_control.js:381:31)
        at Socket.emit (node:events:536:35)
        at Socket.emitReserved (C:\Users\sdmcl\repos\github\node-red-dashboard\node_modules\socket.io\dist\typed-events.js:56:22)
        at Socket._onclose (C:\Users\sdmcl\repos\github\node-red-dashboard\node_modules\socket.io\dist\socket.js:554:14)
        at Client.onclose (C:\Users\sdmcl\repos\github\node-red-dashboard\node_modules\socket.io\dist\client.js:247:20)
        at Socket.emit (node:events:536:35)
        at Socket.onClose (C:\Users\sdmcl\repos\github\node-red-dashboard\node_modules\engine.io\build\socket.js:320:18)
        at Object.onceWrapper (node:events:638:28)
        at WebSocket.emit (node:events:524:28)
        at WebSocket.onClose (C:\Users\sdmcl\repos\github\node-red-dashboard\node_modules\engine.io\build\transport.js:114:14)

Unfortunately, I cannot recreate this!

I think until the issue is fully understood, we can contain this by guarding the call to send in the websocket callbacks disconnect and connect...

nodes/widgets/ui_control.js

    connection: function (conn) {
                    if (config.events === 'all' || config.events === 'connect') {
                        const wNode = RED.nodes.getNode(node.id)
                        /* ↓ ADD GUARD ↓*/
                        if (!wNode) {
                            // log a warning?
                            return
                        }
                        /* ↑ ADD GUARD ↑*/
                        let msg = {
                            payload: 'connect'
                        }
                        msg = addConnectionCredentials(RED, msg, conn, ui)
                        wNode.send(msg) // CRASHES HERE WITHOUT GUARD
                    }
                },
                disconnect: function (conn) {
                    if (config.events === 'all' || config.events === 'connect') {
                        const wNode = RED.nodes.getNode(node.id)
                        /* ↓ ADD GUARD ↓*/
                        if (!wNode) {
                            // log a warning?
                            return
                        }
                        /* ↑ ADD GUARD ↑*/
                        let msg = {
                            payload: 'lost'
                        }
                        msg = addConnectionCredentials(RED, msg, conn, ui)
                        wNode.send(msg) // CRASHES HERE WITHOUT GUARD
                    }
                },

Alternatively, wrap in a try..catch

Steve-Mcl avatar Jun 30 '25 08:06 Steve-Mcl

I got this again this morning.

Steps to recreate:

  1. Deploy a flow with some ui widget and a ui-control node
  2. Open/refresh the dashboard browser
  3. Delete the ui-control node
  4. Deploy (nodes only mode)
  5. Refresh dashboard browser
    • this resulted in Exception has occurred: TypeError: Cannot read properties of null (reading 'send')
    • found wNode is null

What is weird is ui-base.deregister is called from node.on('close' before the disconnect event fires however, the deregister function appears to yield when calling socket.off for the bound events. This results in disconnect event firing and thus the crash

It is an odd order of events.

A quick containment would be to wrap the call in a try catch or guard it by checking typeof wNode?.send === 'function' however there may be more to this than meets the eye. No time to debug that further at this point.

The error

Image

Exception has occurred: TypeError: Cannot read properties of null (reading 'send')
  at disconnect (C:\Users\sdmcl\repos\github\node-red-dashboard\nodes\widgets\ui_control.js:381:31)
    at Socket.emit (node:events:536:35)
    at Socket.emitReserved (C:\Users\sdmcl\repos\github\node-red-dashboard\node_modules\socket.io\dist\typed-events.js:56:22)
    at Socket._onclose (C:\Users\sdmcl\repos\github\node-red-dashboard\node_modules\socket.io\dist\socket.js:554:14)
    at Client.onclose (C:\Users\sdmcl\repos\github\node-red-dashboard\node_modules\socket.io\dist\client.js:247:20)
    at Socket.emit (node:events:536:35)
    at Socket.onClose (C:\Users\sdmcl\repos\github\node-red-dashboard\node_modules\engine.io\build\socket.js:320:18)
    at Object.onceWrapper (node:events:638:28)
    at WebSocket.emit (node:events:524:28)
    at WebSocket.onClose (C:\Users\sdmcl\repos\github\node-red-dashboard\node_modules\engine.io\build\transport.js:114:14)

Steve-Mcl avatar Jul 02 '25 08:07 Steve-Mcl