Skip to content

Some errors are not being handled in NativeModules genMethod #20364

Description

@tad-lispy

Environment

Scanning folders for symlinks in /Users/tadeusz/Projects/kdv/parent-mobile-app/client/node_modules (35ms)
Environment:
OS: OS X El Capitan 10.11.6
Node: 10.5.0
Yarn: 1.2.1
npm: 6.1.0
Watchman: Not Found
Xcode: Not Found
Android Studio: 3.0 AI-171.4408382
Packages: (wanted => installed)
react: 16.3.1 => 16.3.1
react-native: https://github.com/expo/react-native/archive/sdk-28.0.0.tar.gz => 0.55.4

Description

We believe there is a bug somewhere in NativeModules or MessageQueue modules from BatchedBridge library.

In our application we are using Expo SDK v. 28.0.0 which maps to React Native 0.55.4. We run into a bug when calling Expo.FileSystem.downloadAsync which is indirectly calling genMethod from NativeModules of React Native BatchedBridge library. We are getting a Promise back and we are assigning then and catch callbacks to the returned promise. Neither of the callbacks is called.

We have been able to trace the calls down to genMethod function of NativeModules module from react-native package and it seems that the problem is rooted there, or more likely somewhere in BatchedBridge and MessageQueue modules that are being used there:

returnnewPromise((resolve,reject)=>{BatchedBridge.enqueueNativeCall(moduleID,methodID,args,(data)=>resolve(data),(errorData)=>reject(createErrorFromErrorData(errorData)));});

Here enqueueNativeCall method is called and executes without any apparent error, but neither of the callbacks set in enqueueNativeCall of NativeModules are ever called, which in consequence leaves the Promise never resolved.

We suspect that we have a bug in our code, specifically we do not ask for permissions to access native API. This however should result in some meaningful error. Instead our async logic flow is just lost without a trace. We believe this is a bug in React Native code rather than Expo.

Reproducible Demo

Application code sample:

Promise.resolve(null).then(()=>{console.log("Promise chain started");constpromise=FileSystem.downloadAsync(target,FileSystem.cacheDirectory)console.log(require('util').inspect(promise,{depth: null}));// We see the promise objectreturnpromise// We are silently loosing our flow here}).catch((error)=>{// this is never calledconsole.log("Error caught");console.log(require('util').inspect(error,{depth: null}));}).then((downloaded)=>{// this is never called either})

Metadata

Metadata

Assignees

No one assigned

    Labels

    StaleThere has been a lack of activity on this issue and it may be closed soon.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions