facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.82k stars 24.29k forks source link

Crash: JS Functions are not convertible to dynamic #27203

Closed saghul closed 1 year ago

saghul commented 4 years ago

Application crashes with the following stack trace:

Fatal Exception: com.facebook.jni.CppException: JS Functions are not convertible to dynamic

no stack
       at com.facebook.react.bridge.queue.NativeRunnable.run(NativeRunnable.java)
       at android.os.Handler.handleCallback(Handler.java:873)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:29)
       at android.os.Looper.loop(Looper.java:214)
       at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:232)
       at java.lang.Thread.run(Thread.java:764)

React Native version:

System:
    OS: macOS Mojave 10.14.6
    CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
    Memory: 29.94 MB / 32.00 GB
    Shell: 5.0.7 - /usr/local/bin/bash
  Binaries:
    Node: 10.16.0 - /usr/local/bin/node
    Yarn: 1.17.3 - /usr/local/bin/yarn
    npm: 6.12.0 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 27, 28, 29
      Build Tools: 28.0.3, 29.0.0, 29.0.2
      System Images: android-22 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom, android-26 | Android TV Intel x86 Atom, android-28 | Google APIs Intel x86 Atom
      Android NDK: 20.0.5594570
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5791312
    Xcode: 11.2.1/11B53 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.9 => 16.9.0
    react-native: 0.61.3 => 0.61.3
  npmGlobalPackages:
    react-native-cli: 2.0.1

Steps To Reproduce

Can't reproduce it reliably, I've received tens of crashes on Crashlytics though.

Describe what you expected to happen:

Not a crash.

Snack, code example, screenshot, or link to a repository:

This is the crash:

Fatal Exception: com.facebook.jni.CppException: JS Functions are not convertible to dynamic

no stack
       at com.facebook.react.bridge.queue.NativeRunnable.run(NativeRunnable.java)
       at android.os.Handler.handleCallback(Handler.java:873)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:29)
       at android.os.Looper.loop(Looper.java:214)
       at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:232)
       at java.lang.Thread.run(Thread.java:764)

FTR, this issue seems to be similar to https://github.com/facebook/react-native/issues/25784 but there is no 3 callback method involved as far as I can tell.

rodperottoni commented 4 years ago

I'll repost my comment from #25784: This crash has been happening over the last 2-3 months and I'm on RN 0.61.X as well. Honestly gave up on it and decided to suck it up. Sucks for the users though.

https://user-images.githubusercontent.com/15217227/64571125-317fc600-d3a6-11e9-8962-851e2dd9a151.png

saghul commented 4 years ago

Still hapenning on 0.61.5, even after switching to Hermes.

saghul commented 4 years ago

Created a PR: https://github.com/facebook/react-native/pull/28037

stale[bot] commented 4 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

saghul commented 4 years ago

Not stale. There is a PR open, we have tested the fix will millions of installs. I don’t know why ese to do to get the change in :-(

Flouwrian commented 4 years ago

Not stale. There is a PR open, we have tested the fix will millions of installs. I don’t know why ese to do to get the change in :-(

i would love to have this merged!

Balasnest commented 4 years ago

@rodperottoni @saghul Any workaround for this? Did you manage to get it to work? I am also facing this exact error recently. It started raising more in the latest release.

ppeelman commented 4 years ago

Same here

saghul commented 4 years ago

We keep running with this patch... 🤷‍♀️

zidniryi commented 4 years ago

Same Here Tooo. LMAO

Olovorr commented 3 years ago

Any update? 🤔

ali-irawan commented 3 years ago

already using latest release. and the bug crash is keep occurring.

it is affecting a lot of builds

ali-irawan commented 3 years ago

We keep running with this patch... 🤷‍♀️

How you process the patch ? Any clue. I found out is based on JNI

saghul commented 3 years ago

How you process the patch ? Any clue.

Well, you need to fork RN, apply it and build it, which is really annoying TBH.

I wish someone would take a look at it (it's just a few lines).

Oh, and happy birthday dear bug, I forgot! :-)

leeseonghyun21 commented 3 years ago

Any update? same here on 0.63.4

saghul commented 3 years ago

No update, we continue running with a patched version, which is very annoying on Android... oh well.

benmgreene commented 3 years ago

The PR isn't passing all the tests... that's probably a contributing factor to it not progressing.

saghul commented 3 years ago

As I mentioned about a year ago, those are unrelated, that's just a cop-out excuse. If nobody wants to review it, fine, I've given up on seeing it merged.

benmgreene commented 3 years ago

I see. This is one of the oldest PRs in their backlog, I think it just fell through their review process. Can I suggest simply closing that PR and creating a new one off the same branch?

saghul commented 3 years ago

I don't see how that would help. If anyone wants to, you're more than welcome to take my commit and make a new PR with it.

luskin commented 3 years ago

Does anybody have any idea where to even start in triaging this crash? We pushed a very minor codepush update and are now seeing this crash all the time. Looking at the diff there doesn't appear to be anything that would create this crash, it's all vanilla javascript. Any help would be greatly appreciated!

luskin commented 3 years ago

So we pushed a native update and all the crashes disappeared. Then, we pushed an extremely minor codepush update, just a few lines of generic javascript and all of a sudden we are getting this crash all the time. My guess is that codepush is broken somehow and the crashes are originating from codepush bundles vs. bundles generated with a native release. I have no other data to back this up other than this correlation.

saghul commented 3 years ago

@luskin I have never used codepush myself and still got the crash.

Since you say you pushed a very small update, any chance you can create a reduced test project that shows the problem? This may probably help get the PR through.

SolutionsTeam-hue commented 3 years ago

I have installed...Zap certificate on emulator...Added Proxy...to test my app...and then I get this error...JS Functions are not convertible to dynamic...no stact

JustinmClapperton commented 3 years ago

Well I guess this is still an issue. Im shocked there is no comment from the developers about this. Im assuming this issue stems from some type of code bug in our application code but I cant seem to find it. Any pointers to debugging?

ZaikinaEvgeniya-2 commented 3 years ago

still an issue, can not reproduce it

Pingou commented 2 years ago

For my case, I think it happened at least once when I tried to display an error in a try {} catch (error) { console.log(error.message)}. Unfortunately can't remember what was the error.

evelant commented 2 years ago

This happens to my app if wifi is turned off. Perhaps it's react-native-netinfo?

gigby commented 2 years ago

This happens to my app if wifi is turned off. Perhaps it's react-native-netinfo?

I have the same. Wi-fi is turned off and r-n-netinfo installed

sharjeelaqdus-vend commented 2 years ago

Still i am facing this issue on "react-native": "0.66.4" ? Any help on this?

Here is my package list {

"private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "start": "react-native start", "test": "jest", "lint": "eslint .", "androidBundleDebug": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/", "androidBundleRelease": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/" }, "dependencies": { "@firebase/storage": "^0.6.1", "@invertase/react-native-apple-authentication": "^2.1.2", "@notifee/react-native": "^4.1.0", "@ptomasroos/react-native-multi-slider": "https://github.com/me-usman-khalid/react-native-multi-slider.git", "@react-native-async-storage/async-storage": "^1.15.5", "@react-native-clipboard/clipboard": "^1.8.4", "@react-native-community/cookies": "^5.0.1", "@react-native-community/masked-view": "^0.1.11", "@react-native-community/netinfo": "^8.0.0", "@react-native-community/push-notification-ios": "^1.10.1", "@react-native-firebase/analytics": "12.8.0", "@react-native-firebase/app": "12.8.0", "@react-native-firebase/auth": "12.8.0", "@react-native-firebase/crashlytics": "12.8.0", "@react-native-firebase/dynamic-links": "12.8.0", "@react-native-firebase/installations": "12.8.0", "@react-native-firebase/messaging": "12.8.0", "@react-native-firebase/remote-config": "12.8.0", "@react-native-firebase/storage": "12.8.0", "@react-native-google-signin/google-signin": "^6.0.1", "@react-navigation/material-bottom-tabs": "^6.0.9", "@react-navigation/material-top-tabs": "^6.0.6", "@react-navigation/native": "^6.0.6", "@react-navigation/stack": "^6.0.11", "@talkjs/react-native": "^0.1.0", "ansi-regex": "^5.0.1", "apple-signin-auth": "^1.5.1", "axios": "^0.25.0", "convert-string": "^0.1.0", "firebase-dynamic-links": "^1.1.0", "mixpanel-react-native": "^1.4.1", "moment": "^2.29.2", "nth-check": "^2.0.1", "prop-types": "^15.7.2", "react": "17.0.2", "react-native": "0.66.4", "react-native-apple-authentication": "^2.0.0", "react-native-background-timer": "^2.4.1", "react-native-ble-manager": "^7.5.0", "react-native-config": "^1.4.5", "react-native-device-info": "^8.3.2", "react-native-dropdown-picker": "^5.2.3", "react-native-error-boundary": "^1.1.12", "react-native-fbsdk-next": "^7.3.3", "react-native-geolocation-service": "^5.3.0-beta.4", "react-native-gesture-handler": "^1.10.3", "react-native-image-picker": "^4.0.6", "react-native-image-viewing": "^0.2.1", "react-native-inappbrowser-reborn": "^3.6.3", "react-native-linear-gradient": "^2.5.6", "react-native-localize": "^2.1.5", "react-native-maps": "^0.30.1", "react-native-markdown-display": "^7.0.0-alpha.2", "react-native-markdown-package": "^1.8.1", "react-native-modal": "^12.0.2", "react-native-pager-view": "^5.4.9", "react-native-paper": "^4.9.1", "react-native-push-notification": "^8.1.0", "react-native-reanimated": "^2.3.1", "react-native-safe-area-context": "^3.3.2", "react-native-screens": "^3.10.1", "react-native-settings": "^0.2.3", "react-native-size-matters": "^0.4.0", "react-native-spinkit": "^1.5.1", "react-native-splash-screen": "^3.2.0", "react-native-store-version": "^1.3.2", "react-native-svg": "^12.1.1", "react-native-tab-view": "^3.1.1", "react-native-typewriter": "^0.7.0", "react-native-vector-icons": "^8.1.0", "react-native-video": "^5.1.1", "react-native-video-controls": "^2.8.1", "react-native-view-shot": "^3.1.2", "react-native-webview": "^11.13.0", "react-navigation-tabs": "^2.11.1", "react-redux": "^7.2.4", "redux": "^4.1.0", "redux-saga": "^1.1.3", "rn-placeholder": "^3.0.3", "underscore": "^1.13.1", "utf8": "^3.0.0" }, "resolutions": { "ansi-regex": "^5.0.1", "underscore": "^1.13.1", "nth-check": "^2.0.1" }, "devDependencies": { "@babel/core": "^7.14.3", "@babel/runtime": "^7.14.0", "@react-native-community/eslint-config": "^2.0.0", "babel-jest": "^27.0.2", "eslint": "^7.32.0", "eslint-config-airbnb": "^19.0.1", "eslint-plugin-import": "^2.25.3", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-react": "^7.27.1", "eslint-plugin-react-hooks": "^4.3.0", "jest": "^27.0.4", "metro-react-native-babel-preset": "^0.66.2", "react-native-codegen": "^0.0.7", "react-native-flipper": "^0.138.0", "react-test-renderer": "17.0.2", "redux-flipper": "^2.0.1" }, "jest": { "preset": "react-native" } }

IceOfSummer commented 1 year ago

I happened this because when I invoke a native module, which requires a String param, but I passed it an 'object'

github-actions[bot] commented 1 year ago

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] commented 1 year ago

This issue was closed because it has been stalled for 7 days with no activity.

vthorsteinsson commented 1 year ago

We are seeing this issue in production, causing crashes for users. We are applying @saghul 's patch to mitigate this. From reading the source code, it seems obvious that this patch should be in place - there is a check for function objects in the dynamicFromValue() function (around line 188), converting them to nulls, but not in the dynamicFromValueShallow() function, which is the one that @saghul 's associated PR is patching.

d4rky-pl commented 10 months ago

still an issue

vthorsteinsson commented 10 months ago

We ended up finding out where the error originated, in our case. It was an Axios error instance (see https://github.com/axios/axios/blob/b3be36585884ba1e237fdd0eacf55f678aefc396/lib/core/AxiosError.js) that was being thrown as an exception. These instances contain several function objects - and for some reason, React Native on Android is unable to serialize them between threads. The JSC engine even seems to go haywire, after reporting the error cited in this issue. We modified our code to create a much simpler exception object out of an Axios error instance and throw that one instead, and this solved the issue for us.

navignaw commented 6 months ago

We ran into the same issue as @vthorsteinsson and determined it was also due to an Axios error instance which contains functions! In case it's useful, I included a snippet of the function we wrote to recursively clean up objects with functions inside them, mapping them to strings.

type RecursiveMapFunctionToString<T> =
  T extends Function
    ? string
    : T extends object
    ? { [K in keyof T]: RecursiveMapFunctionToString<T[K]> }
    : T

/**
 * Takes an object and returns a new object with functions mapped to strings.
 * This is required because React Native crashes when trying to serialize functions
 * (see https://github.com/facebook/react-native/issues/27203#issuecomment-1836330480)
 */
export function cleanFieldOrObject<T>(value: T): RecursiveMapFunctionToString<T>
export function cleanFieldOrObject<T>(
  value: T
): string | Record<string, unknown> | T {
  if (typeof value === 'function') {
    return value.toString()
  }
  if (typeof value === 'object' && value != null) {
    return Object.keys(value).reduce((acc, key) => {
      acc[key] = cleanFieldOrObject(value[key as keyof typeof value])
      return acc
    }, {} as Record<string, unknown>)
  }
  return value
}
dprevost-LMI commented 3 months ago

Be cautious with the above; we had some side effects:

Test well!

EDIT: Nevertheless, big thanks, @vthorsteinsson & @navignaw, for the pointer; it has indeed helped us scope to the AxiosError and find a path for a fix instead of "running around like a chicken with their head cut off." 😄

navignaw commented 3 months ago

Be cautious with the above; we had some side effects:

  • The error is no longer an error instance
  • we were using axios-retry, and by doing the above in the interceptor, we seem to have altered the retries.
  • The flag isAxiosError was also not a boolean anymore. Test well!

Rather than running this in the interceptor, we only ran this on the code that sent the data over the React Native bridge (in our case, this was our Datadog logging library). So we still used a regular AxiosError object in all of the JS code, but converted it to a serialized version just before sending it to Datadog.