etherpad-lite icon indicating copy to clipboard operation
etherpad-lite copied to clipboard

Uncaught TypeError: Cannot read property 'length' of undefined

Open ptandler opened this issue 4 years ago • 3 comments

Describe the bug When loading an etherpad, sometimes this error message pops up.

To Reproduce It happens randomly when starting etherpad. In our case, the etherpad is embedded into a different application The chance for this to happen seems to be higher, if you start many clients (open the pads) at the same time.

Expected behavior Well, the error message should not appear ;-)

Screenshots etherpad-length undefined etherpad2

Server (please complete the following information):

  • Etherpad version: 1.8.13
  • OS: Ubuntu 20.04.2
  • Node.js version (node --version): v14.16.1
  • npm version (npm --version): 6.14.12

Desktop (please complete the following information):

  • OS: Window, Linux
  • Browser: Chrome
  • Version 91

Additional context

Uncaught TypeError: Cannot read property 'length' of undefined
    at Object.toggleDropDown (VM6858 pad.js:37)
    at Object.showModal (VM6858 pad.js:43)
    at Object.disconnected (VM6858 pad.js:67)
    at r.<anonymous> (VM6858 pad.js:3)
    at r.emit (VM6857 socket.io.js:6)
    at r.onevent (VM6857 socket.io.js:8)
    at r.onpacket (VM6857 socket.io.js:8)
    at r.<anonymous> (VM6857 socket.io.js:8)
    at r.emit (VM6857 socket.io.js:6)
    at r.ondecoded (VM6857 socket.io.js:6)
toggleDropDown @ pad.js?callback=require.define&v=d63febd6:37
showModal @ pad.js?callback=require.define&v=d63febd6:43
disconnected @ pad.js?callback=require.define&v=d63febd6:67
(anonymous) @ pad.js?callback=require.define&v=d63febd6:3
r.emit @ index.js:83
r.onevent @ index.js:83
r.onpacket @ index.js:83
(anonymous) @ index.js:83
r.emit @ index.js:83
r.ondecoded @ index.js:83
(anonymous) @ index.js:83
r.emit @ index.js:83
a.add @ index.js:83
r.ondata @ index.js:83
(anonymous) @ index.js:83
r.emit @ index.js:83
r.onPacket @ index.js:83
(anonymous) @ index.js:83
r.emit @ index.js:83
r.onPacket @ index.js:83
n @ index.js:83
e.decodePayload @ index.js:83
r.onData @ index.js:83
(anonymous) @ index.js:83
r.emit @ index.js:83
i.onData @ index.js:83
i.onLoad @ index.js:83
hasXDR.e.onreadystatechange @ index.js:83
XMLHttpRequest.send (async)
i.create @ index.js:83
i @ index.js:83
o.request @ index.js:83
o.doPoll @ index.js:83
r.poll @ index.js:83
r.onData @ index.js:83
(anonymous) @ index.js:83
r.emit @ index.js:83
i.onData @ index.js:83
i.onLoad @ index.js:83
hasXDR.e.onreadystatechange @ index.js:83
XMLHttpRequest.send (async)
i.create @ index.js:83
i @ index.js:83
o.request @ index.js:83
o.doPoll @ index.js:83
r.poll @ index.js:83
r.onData @ index.js:83
(anonymous) @ index.js:83
r.emit @ index.js:83
i.onData @ index.js:83
i.onLoad @ index.js:83
hasXDR.e.onreadystatechange @ index.js:83
XMLHttpRequest.send (async)
i.create @ index.js:83
i @ index.js:83
o.request @ index.js:83
o.doPoll @ index.js:83
r.poll @ index.js:83
r.doOpen @ index.js:83
r.open @ index.js:83
r.open @ index.js:83
r @ index.js:83
r @ index.js:83
r.open.r.connect @ index.js:83
r @ index.js:83
r @ index.js:83
r @ index.js:83
connect @ pad.js?callback=require.define&v=d63febd6:91
handshake @ pad.js?callback=require.define&v=d63febd6:3
(anonymous) @ pad.js?callback=require.define&v=d63febd6:3
l @ ace2_common.js?callback=require.define&v=d63febd6:38
c @ ace2_common.js?callback=require.define&v=d63febd6:38
setTimeout (async)
(anonymous) @ ace2_common.js?callback=require.define&v=d63febd6:38
u @ ace2_common.js?callback=require.define&v=d63febd6:38
add @ ace2_common.js?callback=require.define&v=d63febd6:38
(anonymous) @ ace2_common.js?callback=require.define&v=d63febd6:38
Deferred @ ace2_common.js?callback=require.define&v=d63febd6:38
then @ ace2_common.js?callback=require.define&v=d63febd6:38
m.fn.ready @ ace2_common.js?callback=require.define&v=d63febd6:38
init @ pad.js?callback=require.define&v=d63febd6:3
init @ pad.js?callback=require.define&v=d63febd6:3
(anonymous) @ Test_143?showChat=false&showLineNumbers=false&lang=de&userName=Peter+Tandler+teambits+(Orga-Team):749
setTimeout (async)
s @ ace2_common.js?callback=require.define&v=d63febd6:56
(anonymous) @ ace2_common.js?callback=require.define&v=d63febd6:56
u @ ace2_common.js?callback=require.define&v=d63febd6:38
fireWith @ ace2_common.js?callback=require.define&v=d63febd6:38
E @ ace2_common.js?callback=require.define&v=d63febd6:38
(anonymous) @ ace2_common.js?callback=require.define&v=d63febd6:38
load (async)
send @ ace2_common.js?callback=require.define&v=d63febd6:38
ajax @ ace2_common.js?callback=require.define&v=d63febd6:38
m.each.m.<computed> @ ace2_common.js?callback=require.define&v=d63febd6:38
getJSON @ ace2_common.js?callback=require.define&v=d63febd6:38
exports.update @ ace2_common.js?callback=require.define&v=d63febd6:56
(anonymous) @ Test_143?showChat=false&showLineNumbers=false&lang=de&userName=Peter+Tandler+teambits+(Orga-Team):741
(anonymous) @ Test_143?showChat=false&showLineNumbers=false&lang=de&userName=Peter+Tandler+teambits+(Orga-Team):759

ptandler avatar Jun 04 '21 16:06 ptandler

Marking as bug, although I cannot 100% reproduce it. I saw it in the past during reconnects. I assume some code hits toggleDropDown during reconnect, but padeditbar.init was not called yet.

webzwo0i avatar Jun 04 '21 19:06 webzwo0i

I found a race condition that I think is the culprit. I started working on a fix a few months ago, but the fix is much more complicated than I had originally thought so I put it on the back burner. See https://github.com/ether/etherpad-lite/compare/rhansen-collab_client for my work-in-progress commits.

rhansen avatar Jun 05 '21 08:06 rhansen

@rhansen good to hear that you started working on a fix!

might be a stupid question and I haven't looked into any etherpad code yet: but what about adding a simple null check in toggleDropDown()?

As far as I understand, this part closes open drop downs. If t.dropdownsis undefined, it seems unlikely to me that there is anything to close, any popup-show classes to remove?

ptandler avatar Jun 06 '21 11:06 ptandler