react-native-ui-kitten: On iOS app crashes with the message "Got unexpected undefined"

🐛 Bug Report

The bug seems to occur only on iOS on one app of mine with a very confusing behavior.

To Reproduce

Steps to reproduce the behavior: On my app:

  • navigate to a screen containing a Select component ;
  • open the Select popover (no need to select another item) ;
  • navigate to next screen ;
  • go back to first screen.

App crashes in release mode / Red screens in debug mode with the message “Got unexpected undefined” pointing to measureSelf function in “node_modules/@ui-kitten/components/devsupport/components/measure/measure.component.js”.

If you don’t open the Select popover there is no crash.

A quick session with Flipper shows that measureSelf passes “null” in the “node” variable. It seems to be a problem about the Select component keeping reacting to system events after being unmounted… Adding a setTimeout() does not solve anything. I’m fixing it with a patch adding a null check on the node variable before calling measureInWindow(). I’ll work on a repro and a PR as soon as possible.

Expected behavior

App doesn’t crash 😃

Link to runnable example or repository (highly encouraged)

I’ll try to take time to produce one later.

UI Kitten and Eva version

Package Version
@eva-design/eva 2.1.1
@ui-kitten/components 5.1.2

Environment information

    OS: macOS 13.5.2
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
  Binaries:
    Node: 16.20.2 - ~/.nvm/versions/node/v16.20.2/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 8.19.4 - ~/Sources/Adoria/adoria-start/node_modules/.bin/npm
    pnpm: 8.9.0 - /usr/local/bin/pnpm
    Watchman: 2023.08.28.00 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: DriverKit 23.0, iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0
  IDEs:
    Android Studio: 2022.2 AI-222.4459.24.2221.10121639
    Xcode: 15.0/15A240d - /usr/bin/xcodebuild
  npmPackages:
    react: 18.2.0 => 18.2.0 
    react-native: 0.72.5 => 0.72.5 

About this issue

  • Original URL
  • State: open
  • Created 9 months ago
  • Reactions: 14
  • Comments: 26 (1 by maintainers)

Commits related to this issue

Most upvoted comments

For those using yarn patch or patch-package, here’s the patch I’m using:

diff --git a/node_modules/@ui-kitten/components/devsupport/components/measure/measure.component.js b/node_modules/@ui-kitten/components/devsupport/components/measure/measure.component.js
index 02180f9..b51cca0 100644
--- a/node_modules/@ui-kitten/components/devsupport/components/measure/measure.component.js
+++ b/node_modules/@ui-kitten/components/devsupport/components/measure/measure.component.js
@@ -42,7 +42,7 @@ const MeasureElement = (props) => {
         if (frame.origin.x < window.size.width) {
             return frame;
         }
-        const boundFrame = new type_1.Frame(frame.origin.x - window.size.width, frame.origin.y, frame.size.width, frame.size.height);
+        const boundFrame = new type_1.Frame(frame.origin.x - window.size.width, frame.origin.y, Math.round(frame.size.width), Math.round(frame.size.height));
         return bindToWindow(boundFrame, window);
     };
     const onUIManagerMeasure = (x, y, w, h) => {
@@ -51,13 +51,13 @@ const MeasureElement = (props) => {
         }
         else {
             const originY = props.shouldUseTopInsets ? y + react_native_1.StatusBar.currentHeight || 0 : y;
-            const frame = bindToWindow(new type_1.Frame(x, originY, w, h), type_1.Frame.window());
+            const frame = bindToWindow(new type_1.Frame(x, originY, Math.round(w), Math.round(h)), type_1.Frame.window());
             props.onMeasure(frame);
         }
     };
     const measureSelf = () => {
         const node = (0, react_native_1.findNodeHandle)(ref.current);
-        react_native_1.UIManager.measureInWindow(node, onUIManagerMeasure);
+        if (node) react_native_1.UIManager.measureInWindow(node, onUIManagerMeasure);
     };
     if (props.force) {
         measureSelf();

Experiencing the same issue with 5.3.1, it happens some time between navigations but not every time, really hard to narrow down what’s really happening 🤔

The solution is in measure.component.js to check for if (node):

 const measureSelf = () => {
        const node = (0, react_native_1.findNodeHandle)(ref.current);
        //react_native_1.UIManager.measureInWindow(node, onUIManagerMeasure);
        if (node) {
            react_native_1.UIManager.measureInWindow(node, onUIManagerMeasure);
        }
    };

However, I guess either a new release is needed or a patch, but not too confident

@GoDeepBlue you can patch UI Kitten with the code from my PR as a temporary solution until the PR is merged. For this specific problem, the fix is at line 78 in https://github.com/akveo/react-native-ui-kitten/pull/1790/files I have 2 apps on which this patch prevented the crash to be reported by crashlytics and sentry, one is patched with patch-package because it’s a Yarn 1.x project, the other with yarn patch, both are ok now

Hi @adrianlzx1996 and @brunomartins-com ! First of all: don’t just edit directly the source files in node_modules because each time you’ll do a dependencies install (through npm or yarn), your edition will be deleted. You need to create a patch, there are basically 2 ways to do that and it depends if you use yarn 2+ or not. For yarn 2+ you can use the built-in feature yarn patch, doc is there: https://yarnpkg.com/cli/patch For yarn 1.x or npm, you can use the “patch-package” devDependency, here is tutorial: https://dev.to/zhnedyalkow/the-easiest-way-to-patch-your-npm-package-4ece Anyway, for both tools the procedure is the same: once the tool is operational make your edition to the source code of your dependency in node_modules and launch the patch procedure, it will generate a patch (a file telling your dependencies manager that it needs to modify one dependency after its install and how to modify it)

Hey @psegalen thanks for your advise and reply!

Hi @adrianlzx1996 and @brunomartins-com ! First of all: don’t just edit directly the source files in node_modules because each time you’ll do a dependencies install (through npm or yarn), your edition will be deleted. You need to create a patch, there are basically 2 ways to do that and it depends if you use yarn 2+ or not. For yarn 2+ you can use the built-in feature yarn patch, doc is there: https://yarnpkg.com/cli/patch For yarn 1.x or npm, you can use the “patch-package” devDependency, here is tutorial: https://dev.to/zhnedyalkow/the-easiest-way-to-patch-your-npm-package-4ece Anyway, for both tools the procedure is the same: once the tool is operational make your edition to the source code of your dependency in node_modules and launch the patch procedure, it will generate a patch (a file telling your dependencies manager that it needs to modify one dependency after its install and how to modify it)

Thank you @psegalen, I implemented the fix and seems to be working so far! You are🥇 😃

I am receiving the same issue. Version is js on “@ui-kitten/components”: “^5.3.1” and “react-native”: “^0.73.1”

Issue occurs while navigating between screens and I have spent a ton of time trying to narrow down the bug. 😕

Basically produces: ERROR Error: Got unexpected undefined, js engine: hermes

Then trace gets to: …/node_modules/@ui-kitten/components/devsupport/components/measure/measure.component.js with code error spawn code ENOENT

Any help or workarounds? I am stuck 😦