Skip to content

Commit

Permalink
fix: android native rejections should be instanceof Error (facebook#4…
Browse files Browse the repository at this point in the history
…4487)

Summary:
fix facebook#44050

## Changelog:

[ANDROID] [FIXED] - fix: android native rejections should be instanceof Error

Pull Request resolved: facebook#44487

Test Plan: reject returns Error.

Reviewed By: NickGerleman

Differential Revision: D57205131

Pulled By: javache

fbshipit-source-id: a5950481d0c4909be4dbea0b430e75222258ae68
  • Loading branch information
huzhanbo1996 authored and facebook-github-bot committed May 14, 2024
1 parent 7dd91d3 commit 62cbdbb
Showing 1 changed file with 53 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,38 @@ struct JNIArgs {
std::vector<jobject> globalRefs_;
};

jsi::Value createJSRuntimeError(
jsi::Runtime& runtime,
const std::string& message) {
return runtime.global()
.getPropertyAsFunction(runtime, "Error")
.call(runtime, message);
}

jsi::Value createRejectionError(jsi::Runtime& rt, const folly::dynamic& args) {
react_native_assert(
args.size() == 1 && "promise reject should has only one argument");

auto value = jsi::valueFromDynamic(rt, args[0]);
react_native_assert(value.isObject() && "promise reject should return a map");

const jsi::Object& valueAsObject = value.asObject(rt);

auto messageProperty = valueAsObject.getProperty(rt, "message");
auto jsError =
createJSRuntimeError(rt, messageProperty.asString(rt).utf8(rt));

auto jsErrorAsObject = jsError.asObject(rt);
auto propertyNames = valueAsObject.getPropertyNames(rt);
for (size_t i = 0; i < propertyNames.size(rt); ++i) {
auto propertyName = jsi::PropNameID::forString(
rt, propertyNames.getValueAtIndex(rt, i).asString(rt));
jsErrorAsObject.setProperty(
rt, propertyName, valueAsObject.getProperty(rt, propertyName));
}
return jsError;
}

auto createJavaCallback(
jsi::Runtime& rt,
jsi::Function&& function,
Expand All @@ -98,7 +130,6 @@ auto createJavaCallback(
LOG(FATAL) << "Callback arg cannot be called more than once";
return;
}

callback->call([args = std::move(args)](
jsi::Runtime& rt, jsi::Function& jsFunction) {
std::vector<jsi::Value> jsArgs;
Expand All @@ -112,6 +143,26 @@ auto createJavaCallback(
});
}

auto createJavaRejectCallback(
jsi::Runtime& rt,
jsi::Function&& function,
std::shared_ptr<CallInvoker> jsInvoker) {
std::optional<AsyncCallback<>> callback(
{rt, std::move(function), std::move(jsInvoker)});
return JCxxCallbackImpl::newObjectCxxArgs(
[callback = std::move(callback)](folly::dynamic args) mutable {
if (!callback) {
LOG(FATAL) << "Callback arg cannot be called more than once";
return;
}
callback->call([args = std::move(args)](
jsi::Runtime& rt, jsi::Function& jsFunction) {
jsFunction.call(rt, createRejectionError(rt, args));
});
callback = std::nullopt;
});
}

struct JPromiseImpl : public jni::JavaClass<JPromiseImpl> {
constexpr static auto kJavaDescriptor =
"Lcom/facebook/react/bridge/PromiseImpl;";
Expand Down Expand Up @@ -407,14 +458,6 @@ jsi::Value convertFromJMapToValue(JNIEnv* env, jsi::Runtime& rt, jobject arg) {
return jsi::valueFromDynamic(rt, result->cthis()->consume());
}

jsi::Value createJSRuntimeError(
jsi::Runtime& runtime,
const std::string& message) {
return runtime.global()
.getPropertyAsFunction(runtime, "Error")
.call(runtime, message);
}

/**
* Creates JSError with current JS runtime stack and Throwable stack trace.
*/
Expand Down Expand Up @@ -855,7 +898,7 @@ jsi::Value JavaTurboModule::invokeJavaMethod(
runtime,
args[0].getObject(runtime).getFunction(runtime),
jsInvoker_);
auto reject = createJavaCallback(
auto reject = createJavaRejectCallback(
runtime,
args[1].getObject(runtime).getFunction(runtime),
jsInvoker_);
Expand Down

0 comments on commit 62cbdbb

Please sign in to comment.