fix: android native rejections should be instanceof Error (#44487)

Summary:
fix https://github.com/facebook/react-native/issues/44050

## Changelog:

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

Pull Request resolved: https://github.com/facebook/react-native/pull/44487

Test Plan: reject returns Error.

Reviewed By: NickGerleman

Differential Revision: D57205131

Pulled By: javache

fbshipit-source-id: a5950481d0c4909be4dbea0b430e75222258ae68
This commit is contained in:
huzhanbo.luc
2024-05-14 04:57:01 -07:00
committed by Facebook GitHub Bot
parent 7dd91d3437
commit 62cbdbbcc6
@@ -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,
@@ -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;
@@ -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;";
@@ -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.
*/
@@ -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_);