Skip to content

Bridge promises don't handle multiple resolve or reject calls properly #20262

@esprehn

Description

@esprehn

Environment

Environment:
OS: macOS High Sierra 10.13.5
Node: 8.9.4
Yarn: 1.5.1
npm: 5.6.0
Watchman: 4.7.0
Xcode: Xcode 9.4.1 Build version 9F2000
Android Studio: 3.1 AI-173.4720617

Packages: (wanted => installed)
react: 16.2.0 => 16.2.0
react-native: 0.54.4 => 0.54.4

Description

PromiseImpl and RCTModuleMethod don't handle promise resolution properly. Resolving a promise a second time is supposed to have no effect per ES semantics, similarly rejecting it a second time, or if it's rejected already, should have no effect.

PromiseImpl.resolve a second time will throw an error:

Exception java.lang.RuntimeException: Illegal callback invocation from native module. This callback type only permits a single invocation from native code.
com.facebook.react.bridge.CallbackImpl.invoke (CallbackImpl.java:30)
com.facebook.react.bridge.PromiseImpl.resolve (PromiseImpl.java:32)

For iOS this doesn't crash in ObjC, instead it sends another message over the bridge, but the callbacks are gone, so it incorrectly warns in a dev build (Callback with id ${cbID}: ${module}.${method}() not found) and is correctly a no-op in a release build (though it is inefficient to send the bridge response).

Reproducible Demo

Create a @RectMethod and do resolve() in the Java twice, or do do resolve twice in an ObjC iOS method.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugRan CommandsOne of our bots successfully processed a command.Resolution: LockedThis issue was locked by the bot.Resolution: PR SubmittedA pull request with a fix has been provided.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions