glimmer-vm icon indicating copy to clipboard operation
glimmer-vm copied to clipboard

TypeError: Cannot read properties of undefined (reading 'lastNode')

Open johanrd opened this issue 2 years ago • 3 comments

I see TypeError: Cannot read properties of undefined (reading 'lastNode') from time to time popping up in Sentry:

Screen Shot 2022-11-15 at 12 21 15

https://github.com/glimmerjs/glimmer-vm/blob/master/packages/@glimmer/runtime/lib/vm/element-builder.ts#L506-L515

I have yet to reproduce it when I try, unfortunately. Any ideas on what may be causing this? Possibly related to #1372 and https://github.com/emberjs/ember.js/issues/18520


Environment: @glimmer/component: "^1.1.1", ember-source: "4.8.0", Browser: Chrome 107.0.0 OS: Windows 10

johanrd avatar Nov 15 '22 11:11 johanrd

@johanrd it's likely related to google page translate or any extensions, modifying dom nodes

lifeart avatar Nov 15 '22 15:11 lifeart

@lifeart Yes, that may very well be.

As commented on https://github.com/glimmerjs/glimmer-vm/issues/1372#issuecomment-1314515038, I don't think it is a very viable solution to tell users to uninstall various chrome extensions and/or not use google translate in order to not break a glimmer app.

Is it possible with a more resilient handling? E.g. by applying optional chaining on tail.lastNode()? (if that does not break browser support or other parts too much)

// https://github.com/glimmerjs/glimmer-vm/blob/master/packages/@glimmer/runtime/lib/vm/element-builder.ts#L506-L515

lastNode(): SimpleNode {
    let boundList = this.boundList;

    let tail = expect(
      boundList[boundList.length - 1],
      'cannot call `lastNode()` while `LiveBlockList` is still initializing'
    );

-    return tail.lastNode();
+    return tail?.lastNode();
  }

johanrd avatar Nov 16 '22 09:11 johanrd

This issue appears to result from the usage of htmlSafe from @ember/template. It happens when the htmlSafe outputted code is torn down/updated after it has been translated w/ Google Translate (or similar tool). Oddly, adding a wrapper element to the htmlSafe output fixes the issue - though not a reasonable solution in most cases.

htmlSafe(`<span>${someValue}</span>`)

golampo avatar Jan 12 '23 20:01 golampo