Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix access to undefined exception #4219

Merged
merged 3 commits into from
Nov 27, 2023

Conversation

billti
Copy link
Contributor

@billti billti commented Nov 26, 2023

Running some code locally and I was regularly hitting an error Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'is'). I tracked it down to the line fixed in this PR.

It would appear that sometimes newVNode.props may be undefined, so guarding against that.

Copy link

github-actions bot commented Nov 26, 2023

📊 Tachometer Benchmark Results

Summary

duration

  • 02_replace1k: unsure 🔍 -1% - +2% (-0.81ms - +1.66ms)
    preact-local vs preact-main
  • 03_update10th1k_x16: faster ✔ 1% - 8% (0.19ms - 2.68ms)
    preact-local vs preact-main
  • 07_create10k: unsure 🔍 -0% - +1% (-4.08ms - +9.87ms)
    preact-local vs preact-main
  • filter_list: unsure 🔍 -3% - +1% (-0.52ms - +0.18ms)
    preact-local vs preact-main
  • hydrate1k: unsure 🔍 -2% - +2% (-1.78ms - +1.44ms)
    preact-local vs preact-main
  • many_updates: unsure 🔍 -3% - +3% (-0.53ms - +0.47ms)
    preact-local vs preact-main
  • text_update: unsure 🔍 -4% - +2% (-0.10ms - +0.05ms)
    preact-local vs preact-main
  • todo: unsure 🔍 -2% - +1% (-0.47ms - +0.18ms)
    preact-local vs preact-main

usedJSHeapSize

  • 02_replace1k: unsure 🔍 -0% - +0% (-0.00ms - +0.00ms)
    preact-local vs preact-main
  • 03_update10th1k_x16: unsure 🔍 -0% - +0% (-0.01ms - +0.00ms)
    preact-local vs preact-main
  • 07_create10k: unsure 🔍 -0% - +0% (-0.00ms - +0.00ms)
    preact-local vs preact-main
  • filter_list: unsure 🔍 -1% - +1% (-0.02ms - +0.01ms)
    preact-local vs preact-main
  • hydrate1k: unsure 🔍 -0% - +0% (-0.00ms - +0.01ms)
    preact-local vs preact-main
  • many_updates: unsure 🔍 -0% - +0% (-0.02ms - +0.01ms)
    preact-local vs preact-main
  • text_update: unsure 🔍 -2% - +0% (-0.01ms - +0.00ms)
    preact-local vs preact-main
  • todo: unsure 🔍 +0% - +0% (+0.00ms - +0.00ms)
    preact-local vs preact-main

Results

02_replace1k

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main84.16ms - 85.79ms-unsure 🔍
-2% - +1%
-1.66ms - +0.81ms
unsure 🔍
-2% - +1%
-1.63ms - +0.56ms
preact-local84.47ms - 86.33msunsure 🔍
-1% - +2%
-0.81ms - +1.66ms
-unsure 🔍
-2% - +1%
-1.30ms - +1.08ms
preact-hooks84.77ms - 86.25msunsure 🔍
-1% - +2%
-0.56ms - +1.63ms
unsure 🔍
-1% - +2%
-1.08ms - +1.30ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main3.31ms - 3.32ms-unsure 🔍
-0% - +0%
-0.00ms - +0.00ms
faster ✔
1% - 1%
0.02ms - 0.03ms
preact-local3.31ms - 3.32msunsure 🔍
-0% - +0%
-0.00ms - +0.00ms
-faster ✔
1% - 1%
0.02ms - 0.03ms
preact-hooks3.34ms - 3.34msslower ❌
1% - 1%
0.02ms - 0.03ms
slower ❌
1% - 1%
0.02ms - 0.03ms
-

run-warmup-0

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main33.01ms - 34.41ms-unsure 🔍
-2% - +3%
-0.73ms - +1.12ms
unsure 🔍
-3% - +2%
-1.16ms - +0.84ms
preact-local32.91ms - 34.12msunsure 🔍
-3% - +2%
-1.12ms - +0.73ms
-unsure 🔍
-4% - +2%
-1.29ms - +0.58ms
preact-hooks33.16ms - 34.58msunsure 🔍
-2% - +3%
-0.84ms - +1.16ms
unsure 🔍
-2% - +4%
-0.58ms - +1.29ms
-

run-warmup-1

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main42.99ms - 44.21ms-unsure 🔍
-1% - +3%
-0.58ms - +1.20ms
unsure 🔍
-1% - +3%
-0.48ms - +1.17ms
preact-local42.65ms - 43.94msunsure 🔍
-3% - +1%
-1.20ms - +0.58ms
-unsure 🔍
-2% - +2%
-0.81ms - +0.89ms
preact-hooks42.71ms - 43.81msunsure 🔍
-3% - +1%
-1.17ms - +0.48ms
unsure 🔍
-2% - +2%
-0.89ms - +0.81ms
-

run-warmup-2

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main31.10ms - 31.99ms-unsure 🔍
-2% - +1%
-0.79ms - +0.40ms
faster ✔
0% - 3%
0.05ms - 1.11ms
preact-local31.35ms - 32.13msunsure 🔍
-1% - +3%
-0.40ms - +0.79ms
-unsure 🔍
-3% - +0%
-0.87ms - +0.11ms
preact-hooks31.83ms - 32.41msslower ❌
0% - 4%
0.05ms - 1.11ms
unsure 🔍
-0% - +3%
-0.11ms - +0.87ms
-

run-warmup-3

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main24.57ms - 24.82ms-unsure 🔍
-3% - +0%
-0.75ms - +0.12ms
faster ✔
1% - 2%
0.18ms - 0.58ms
preact-local24.59ms - 25.43msunsure 🔍
-1% - +3%
-0.12ms - +0.75ms
-unsure 🔍
-2% - +2%
-0.51ms - +0.38ms
preact-hooks24.92ms - 25.24msslower ❌
1% - 2%
0.18ms - 0.58ms
unsure 🔍
-2% - +2%
-0.38ms - +0.51ms
-

run-warmup-4

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main40.69ms - 42.08ms-unsure 🔍
-2% - +2%
-0.96ms - +0.90ms
unsure 🔍
-3% - +2%
-1.10ms - +0.69ms
preact-local40.81ms - 42.02msunsure 🔍
-2% - +2%
-0.90ms - +0.96ms
-unsure 🔍
-2% - +2%
-1.00ms - +0.65ms
preact-hooks41.03ms - 42.14msunsure 🔍
-2% - +3%
-0.69ms - +1.10ms
unsure 🔍
-2% - +2%
-0.65ms - +1.00ms
-

run-final

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main23.98ms - 24.58ms-unsure 🔍
-3% - +1%
-0.72ms - +0.17ms
unsure 🔍
-3% - +1%
-0.71ms - +0.14ms
preact-local24.23ms - 24.88msunsure 🔍
-1% - +3%
-0.17ms - +0.72ms
-unsure 🔍
-2% - +2%
-0.45ms - +0.43ms
preact-hooks24.26ms - 24.86msunsure 🔍
-1% - +3%
-0.14ms - +0.71ms
unsure 🔍
-2% - +2%
-0.43ms - +0.45ms
-
03_update10th1k_x16

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main31.54ms - 33.31ms-slower ❌
1% - 9%
0.19ms - 2.68ms
unsure 🔍
-4% - +4%
-1.20ms - +1.31ms
preact-local30.11ms - 31.86msfaster ✔
1% - 8%
0.19ms - 2.68ms
-faster ✔
1% - 8%
0.14ms - 2.63ms
preact-hooks31.48ms - 33.26msunsure 🔍
-4% - +4%
-1.31ms - +1.20ms
slower ❌
0% - 9%
0.14ms - 2.63ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main3.28ms - 3.29ms-unsure 🔍
-0% - +0%
-0.00ms - +0.01ms
faster ✔
0% - 1%
0.01ms - 0.03ms
preact-local3.27ms - 3.29msunsure 🔍
-0% - +0%
-0.01ms - +0.00ms
-faster ✔
0% - 1%
0.01ms - 0.03ms
preact-hooks3.30ms - 3.31msslower ❌
0% - 1%
0.01ms - 0.03ms
slower ❌
0% - 1%
0.01ms - 0.03ms
-
07_create10k

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main947.35ms - 955.68ms-unsure 🔍
-1% - +0%
-9.87ms - +4.08ms
unsure 🔍
-2% - +0%
-14.69ms - +1.70ms
preact-local948.81ms - 960.00msunsure 🔍
-0% - +1%
-4.08ms - +9.87ms
-unsure 🔍
-1% - +1%
-12.61ms - +5.41ms
preact-hooks950.95ms - 965.07msunsure 🔍
-0% - +2%
-1.70ms - +14.69ms
unsure 🔍
-1% - +1%
-5.41ms - +12.61ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main26.32ms - 26.32ms-unsure 🔍
-0% - +0%
-0.00ms - +0.00ms
unsure 🔍
-0% - -0%
-0.02ms - -0.02ms
preact-local26.32ms - 26.32msunsure 🔍
-0% - +0%
-0.00ms - +0.00ms
-unsure 🔍
-0% - -0%
-0.02ms - -0.02ms
preact-hooks26.34ms - 26.34msunsure 🔍
+0% - +0%
+0.02ms - +0.02ms
unsure 🔍
+0% - +0%
+0.02ms - +0.02ms
-
filter_list

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main16.69ms - 17.27ms-unsure 🔍
-1% - +3%
-0.18ms - +0.52ms
unsure 🔍
-3% - +2%
-0.58ms - +0.36ms
preact-local16.61ms - 17.01msunsure 🔍
-3% - +1%
-0.52ms - +0.18ms
-unsure 🔍
-4% - +1%
-0.70ms - +0.15ms
preact-hooks16.72ms - 17.46msunsure 🔍
-2% - +3%
-0.36ms - +0.58ms
unsure 🔍
-1% - +4%
-0.15ms - +0.70ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main1.34ms - 1.36ms-unsure 🔍
-1% - +1%
-0.01ms - +0.02ms
faster ✔
1% - 3%
0.01ms - 0.04ms
preact-local1.34ms - 1.36msunsure 🔍
-1% - +1%
-0.02ms - +0.01ms
-faster ✔
1% - 3%
0.01ms - 0.04ms
preact-hooks1.36ms - 1.38msslower ❌
1% - 3%
0.01ms - 0.04ms
slower ❌
1% - 3%
0.01ms - 0.04ms
-
hydrate1k

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main83.38ms - 86.38ms-unsure 🔍
-2% - +2%
-1.44ms - +1.78ms
unsure 🔍
-2% - +2%
-1.71ms - +1.98ms
preact-local84.12ms - 85.31msunsure 🔍
-2% - +2%
-1.78ms - +1.44ms
-unsure 🔍
-1% - +1%
-1.27ms - +1.20ms
preact-hooks83.67ms - 85.83msunsure 🔍
-2% - +2%
-1.98ms - +1.71ms
unsure 🔍
-1% - +1%
-1.20ms - +1.27ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main6.12ms - 6.12ms-unsure 🔍
-0% - +0%
-0.01ms - +0.00ms
unsure 🔍
-0% - -0%
-0.03ms - -0.02ms
preact-local6.12ms - 6.13msunsure 🔍
-0% - +0%
-0.00ms - +0.01ms
-unsure 🔍
-0% - -0%
-0.03ms - -0.01ms
preact-hooks6.14ms - 6.15msunsure 🔍
+0% - +0%
+0.02ms - +0.03ms
unsure 🔍
+0% - +0%
+0.01ms - +0.03ms
-
many_updates

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main16.88ms - 17.42ms-unsure 🔍
-3% - +3%
-0.47ms - +0.53ms
unsure 🔍
-3% - +2%
-0.60ms - +0.36ms
preact-local16.70ms - 17.54msunsure 🔍
-3% - +3%
-0.53ms - +0.47ms
-unsure 🔍
-4% - +2%
-0.73ms - +0.42ms
preact-hooks16.88ms - 17.66msunsure 🔍
-2% - +3%
-0.36ms - +0.60ms
unsure 🔍
-2% - +4%
-0.42ms - +0.73ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main4.46ms - 4.48ms-unsure 🔍
-0% - +0%
-0.01ms - +0.02ms
faster ✔
0% - 1%
0.00ms - 0.04ms
preact-local4.46ms - 4.47msunsure 🔍
-0% - +0%
-0.02ms - +0.01ms
-faster ✔
0% - 1%
0.01ms - 0.04ms
preact-hooks4.48ms - 4.51msslower ❌
0% - 1%
0.00ms - 0.04ms
slower ❌
0% - 1%
0.01ms - 0.04ms
-
text_update

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main2.53ms - 2.63ms-unsure 🔍
-2% - +4%
-0.05ms - +0.10ms
faster ✔
5% - 11%
0.15ms - 0.31ms
preact-local2.50ms - 2.61msunsure 🔍
-4% - +2%
-0.10ms - +0.05ms
-faster ✔
6% - 12%
0.17ms - 0.34ms
preact-hooks2.75ms - 2.87msslower ❌
6% - 12%
0.15ms - 0.31ms
slower ❌
7% - 13%
0.17ms - 0.34ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main0.77ms - 0.78ms-unsure 🔍
-0% - +2%
-0.00ms - +0.01ms
unsure 🔍
-1% - +1%
-0.01ms - +0.01ms
preact-local0.76ms - 0.77msunsure 🔍
-2% - +0%
-0.01ms - +0.00ms
-unsure 🔍
-2% - +0%
-0.01ms - +0.00ms
preact-hooks0.77ms - 0.78msunsure 🔍
-1% - +1%
-0.01ms - +0.01ms
unsure 🔍
-0% - +2%
-0.00ms - +0.01ms
-
todo

duration

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main27.70ms - 28.33ms-unsure 🔍
-1% - +2%
-0.18ms - +0.47ms
faster ✔
2% - 6%
0.62ms - 1.67ms
preact-local27.79ms - 27.96msunsure 🔍
-2% - +1%
-0.47ms - +0.18ms
-faster ✔
3% - 6%
0.86ms - 1.71ms
preact-hooks28.74ms - 29.58msslower ❌
2% - 6%
0.62ms - 1.67ms
slower ❌
3% - 6%
0.86ms - 1.71ms
-

usedJSHeapSize

VersionAvg timevs preact-mainvs preact-localvs preact-hooks
preact-main0.79ms - 0.79ms-unsure 🔍
-0% - -0%
-0.00ms - -0.00ms
faster ✔
3% - 3%
0.03ms - 0.03ms
preact-local0.79ms - 0.79msunsure 🔍
+0% - +0%
+0.00ms - +0.00ms
-faster ✔
3% - 3%
0.02ms - 0.03ms
preact-hooks0.81ms - 0.81msslower ❌
3% - 3%
0.03ms - 0.03ms
slower ❌
3% - 3%
0.02ms - 0.03ms
-

tachometer-reporter-action v2 for Benchmarks

@billti
Copy link
Contributor Author

billti commented Nov 27, 2023

I should note, I hit this on 10.18.1. I tried updating to 10.19.2 and the issue persisted. I identified the issue and verified the fix by adding the ?to document.createElement(x,w?.is&&w) in "dist/preact.module.js" locally (which is what my bundler picks up), but to support older browsers went with the more verbose 'old school' syntax in this PR. I can update it as needed.

I opened on 'main' as I see the same code exists there, but I can backport if desired.

@JoviDeCroock
Copy link
Member

Mind giving some way to reproduce this issue as props are defaulted to an object https://github.com/preactjs/preact/blob/main/src/create-element.js

@billti
Copy link
Contributor Author

billti commented Nov 27, 2023

It was in the middle of a larger codebase and only happened sporadically, but I'll try and conjure up a minimal repo.

I assumed it could be null as a few lines later (427) it seems to check if it could have been null on the old node (via oldProps = oldVNode.props || EMPTY_OBJ;).

@JoviDeCroock
Copy link
Member

JoviDeCroock commented Nov 27, 2023

A repro or test case would be needed either way so we can prevent regressions. The old node is indeed nullable, this is during the creation scenario but then the new one is still defined

@billti
Copy link
Contributor Author

billti commented Nov 27, 2023

OK. Just narrowed it down and got a minimal repro.

It's a bug in my app's code, but I believe it still shouldn't be throwing an unhandled exception here. Basically, in one scenario it was passing an object for what should have been a string which is rendered in a text node location. This renders without error first time through, but on the re-render on changing some state unrelated to the problematic node, it throws the error.

Load the below on an empty document, and when you click the checkbox to cause the re-render you'll see the issue. As the commented line states, if data is a string instead of an object (as it was supposed to be), then it re-renders fine.

import { render } from "preact";
import { useState } from "preact/hooks";

window.onload = () => {
  // *** If data is a string, it works fine ***
  const data = { a: 10, b: "hello" };
  render(<ReproApp data={data} />, document.body);
};

function ReproApp({ data }: any) {
  const [showDetail, setShowDetail] = useState(false);

  const toggleDetail = () => {
    setShowDetail(!showDetail);
  };

  return (
    <>
      <p>Check the box to cause the error</p>
      <input type="checkbox" checked={showDetail} onClick={toggleDetail} />
      <div>{data}</div>
    </>
  );
}

@marvinhagemeister
Copy link
Member

marvinhagemeister commented Nov 27, 2023

Thanks for providing a minimal test reproduction! Took the liberty of updating the PR. The observed issue is a symptom of another cause in that recent refactors lead to invalid vnodes being passed to createVNode.

@coveralls
Copy link

coveralls commented Nov 27, 2023

Coverage Status

coverage: 99.463%. remained the same
when pulling 02ad4e2 on billti:billti/fix-is-access
into 3eb790c on preactjs:main.

@billti
Copy link
Contributor Author

billti commented Nov 27, 2023

Great! Thanks for the 'correct' fix, and super-fast turnaround. I love the project and use it whenever I can, so thanks for your work on it.

@marvinhagemeister marvinhagemeister merged commit 2629e40 into preactjs:main Nov 27, 2023
13 checks passed
github-merge-queue bot pushed a commit to microsoft/qsharp that referenced this pull request Dec 13, 2023
Moving to 10.19.3 as it has my picture on it. (For a reason - it fixes
the issue I hit when developing the widgets,
preactjs/preact#4219).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants