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

Fixed issue with hermes and prototype.toString #814

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

marconett
Copy link

I was running into issues when rendering the datetimepicker on Android in release mode only (dev worked fine).
Opening the Picker crashed my app (stacktrace attached).

Looking through the trace, i narrowed it down to an issue with the line if (Object.prototype.toString.call(value) === '[object Date]') { in toMilliseconds in utils.js.

Wondering why this might be an issue and knowing that "release mode only" bugs are often related to hermes, I found that using Function.prototype.toString is not supported when using hermes (Source: https://hermesengine.dev/docs/language-features/#miscellaneous-incompatibilities).

I therefore changed the way dates are detected. It works for me now.

09-20 15:22:20.248  8181  8236 E ReactNativeJS: TypeError: Object is not a function, js engine: hermes
09-20 15:22:20.265  8181  8237 E AndroidRuntime: FATAL EXCEPTION: mqt_native_modules
09-20 15:22:20.265  8181  8237 E AndroidRuntime: Process: my.app.opsec, PID: 8181
09-20 15:22:20.265  8181  8237 E AndroidRuntime: com.facebook.react.common.JavascriptException: TypeError: Object is not a function, js engine: hermes, stack:
09-20 15:22:20.265  8181  8237 E AndroidRuntime: toString@1:761211
09-20 15:22:20.265  8181  8237 E AndroidRuntime: anonymous@1:757790
09-20 15:22:20.265  8181  8237 E AndroidRuntime: anonymous@1:761297
09-20 15:22:20.265  8181  8237 E AndroidRuntime: loadModuleImplementation@1:37666
09-20 15:22:20.265  8181  8237 E AndroidRuntime: guardedLoadModule@1:37172
09-20 15:22:20.265  8181  8237 E AndroidRuntime: metroRequire@1:36843
09-20 15:22:20.265  8181  8237 E AndroidRuntime: toString@1:761203
09-20 15:22:20.265  8181  8237 E AndroidRuntime: each@1:901982
09-20 15:22:20.265  8181  8237 E AndroidRuntime: toMilliseconds@1:901938
09-20 15:22:20.265  8181  8237 E AndroidRuntime: ?anon_0_@1:901455
09-20 15:22:20.265  8181  8237 E AndroidRuntime: asyncGeneratorStep@1:564346
09-20 15:22:20.265  8181  8237 E AndroidRuntime: _next@1:564616
09-20 15:22:20.265  8181  8237 E AndroidRuntime: anonymous@1:564568
09-20 15:22:20.265  8181  8237 E AndroidRuntime: tryCallTwo@61:8
09-20 15:22:20.265  8181  8237 E AndroidRuntime: doResolve@216:24
09-20 15:22:20.265  8181  8237 E AndroidRuntime: Promise@82:13
09-20 15:22:20.265  8181  8237 E AndroidRuntime: anonymous@1:564489
09-20 15:22:20.265  8181  8237 E AndroidRuntime: open@1:901380
09-20 15:22:20.265  8181  8237 E AndroidRuntime: anonymous@1:903830
09-20 15:22:20.265  8181  8237 E AndroidRuntime: ?anon_0_@1:900212
09-20 15:22:20.265  8181  8237 E AndroidRuntime: asyncGeneratorStep@1:564346
09-20 15:22:20.265  8181  8237 E AndroidRuntime: _next@1:564616
09-20 15:22:20.265  8181  8237 E AndroidRuntime: anonymous@1:564568
09-20 15:22:20.265  8181  8237 E AndroidRuntime: tryCallTwo@61:8
09-20 15:22:20.265  8181  8237 E AndroidRuntime: doResolve@216:24
09-20 15:22:20.265  8181  8237 E AndroidRuntime: Promise@82:13
09-20 15:22:20.265  8181  8237 E AndroidRuntime: anonymous@1:564489
09-20 15:22:20.265  8181  8237 E AndroidRuntime: presentPicker@1:900697
09-20 15:22:20.265  8181  8237 E AndroidRuntime: open@1:899675
09-20 15:22:20.265  8181  8237 E AndroidRuntime: showOrUpdatePicker@1:905348
09-20 15:22:20.265  8181  8237 E AndroidRuntime: commitHookEffectListMount@1:296884
09-20 15:22:20.265  8181  8237 E AndroidRuntime: flushPassiveEffects@1:310457
09-20 15:22:20.265  8181  8237 E AndroidRuntime: anonymous@1:309580
09-20 15:22:20.265  8181  8237 E AndroidRuntime: J@1:251141
09-20 15:22:20.265  8181  8237 E AndroidRuntime: R@1:251472
09-20 15:22:20.265  8181  8237 E AndroidRuntime: anonymous@1:154377
09-20 15:22:20.265  8181  8237 E AndroidRuntime: _callTimer@1:153326
09-20 15:22:20.265  8181  8237 E AndroidRuntime: _callReactNativeMicrotasksPass@1:153490
09-20 15:22:20.265  8181  8237 E AndroidRuntime: callReactNativeMicrotasks@1:155457
09-20 15:22:20.265  8181  8237 E AndroidRuntime: __callReactNativeMicrotasks@1:57794
09-20 15:22:20.265  8181  8237 E AndroidRuntime: anonymous@1:56887
09-20 15:22:20.265  8181  8237 E AndroidRuntime: __guard@1:57635
09-20 15:22:20.265  8181  8237 E AndroidRuntime: flushedQueue@1:56798
09-20 15:22:20.265  8181  8237 E AndroidRuntime: callFunctionReturnFlushedQueue@1:56654
09-20 15:22:20.265  8181  8237 E AndroidRuntime:
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at com.facebook.react.modules.core.ExceptionsManagerModule.reportException(ExceptionsManagerModule.java:72)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:188)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at com.facebook.jni.NativeRunnable.run(Native Method)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at android.os.Handler.handleCallback(Handler.java:942)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:99)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at android.os.Looper.loopOnce(Looper.java:201)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:288)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:228)
09-20 15:22:20.265  8181  8237 E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:1012)

@vonovak
Copy link
Member

vonovak commented Sep 22, 2023

hello and thanks for the PR!
Do you have a repro for your crash? (https://stackoverflow.com/help/minimal-reproducible-example)

The code we have there is a little odd, so this change probably makes sense... But there's a PR which I think is changing it and I'd like to get that one in first.

On another note, I'm not sure the explanation you gave is correct, I think for some reason, in your code, Object.prototype.toString is an Object, instead of it being a function, or some weird value was passed into that code... We're not really inspecting the source code of a function as described in the hermes docs.

@marconett
Copy link
Author

marconett commented Sep 22, 2023

You're right, my fix doesn't directly address the error message. It still fixes the crash in my specific case.

I don't have the time to provide you with a minimal reproducible example, sorry.
I tried reproducing the error inside the hermes playground (https://hermesengine.dev/playground/) but it seems to be working there.

Here's what I tried:

// trying to reproduce the following message:
// TypeError: Object is not a function, js engine: hermes, stack:


// simple test
const value = new Date();
print(Object.prototype.toString.call(value));


// copying additional behavior from datetimepicker
const options = {
    a: new Date(),
    b: null,
    c: undefined,
};
const keys = [ 'a', 'b', 'c', 'd' ];

keys.forEach(function each(key) {
    const value = options[key];

    // if (value instanceof Date) {
    if (Object.prototype.toString.call(value) === '[object Date]') {
      print('found date');
    }
});

The PR you linked made exactly the same change I did, so feel free to close my PR.

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.

2 participants