mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
12a102b926
Summary: This PR is adding examples of Turbo Modules functions throwing runtime exceptions and asserts. This should make it easier to collaborate and develop the error reporting for a new architecture that is being discussed in the React Native New Architecture Working Group -> https://github.com/reactwg/react-native-new-architecture/discussions/122. I'm not sure what return type should be used for the JS function returning `Promise<void>` in Cxx, I used [`AsyncPromise<jsi::Value>`](https://github.com/facebook/react-native/pull/36729/files#diff-9cebc75f48fd35fd6fef71138f98dfd0ba28a754b2aab0d6fe44fd685f74ce16R135), what would you use, I've not found `void` type to use? ### Added functions The table shows the current behavior. <table> <tr> <td> Function <td> Description <td> Turbo Module <td> Cxx Module <tr> <td> voidFuncThrows <td> function with return type void throws a runtime exception <td> platform error no JS stack trace <td> JS error no native stack trace <tr> <td> getObjectThrows <td> function with return type object throws a runtime exception <td> JS error no platform stack trace <td> JS error no native stack trace <tr> <td> promiseThrows <td> function with return type promise throws a runtime exception before settling the promise <td> platform error no JS stack trace <td> JS error no native stack trace <tr> <td> voidFuncAssert <td> function with return type void asserts <td> platform error no JS stack trace <td> native error no JS stack trace <tr> <td> getObjectAssert <td> function with return type object asserts <td> JS error no platform stack trace <td> native error no JS stack trace <tr> <td> promiseAssert <td> function with return type promise asserts before settling the promise <td> platform error no JS stack trace <td> native error no JS stack trace </table> ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [INTERNAL] [ADDED] - Error reporting examples in rn-tester turbo modules Pull Request resolved: https://github.com/facebook/react-native/pull/36729 Test Plan: This PR doesn't change any RN behavior. Only shows the current state by adding an example to rn-tester. I'm happy to add these examples to the unit/integration test, just point me to where would be a good place. Reviewed By: rshest Differential Revision: D44623027 Pulled By: javache fbshipit-source-id: d9cc04852b05d810ed11d7a94f1b2d455ef554a5
185 lines
4.9 KiB
C++
185 lines
4.9 KiB
C++
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#include "NativeCxxModuleExample.h"
|
|
#include <react/debug/react_native_assert.h>
|
|
|
|
namespace facebook::react {
|
|
|
|
NativeCxxModuleExample::NativeCxxModuleExample(
|
|
std::shared_ptr<CallInvoker> jsInvoker)
|
|
: NativeCxxModuleExampleCxxSpec(std::move(jsInvoker)) {}
|
|
|
|
void NativeCxxModuleExample::getValueWithCallback(
|
|
jsi::Runtime &rt,
|
|
AsyncCallback<std::string> callback) {
|
|
callback({"value from callback!"});
|
|
}
|
|
|
|
std::vector<std::optional<ObjectStruct>> NativeCxxModuleExample::getArray(
|
|
jsi::Runtime &rt,
|
|
std::vector<std::optional<ObjectStruct>> arg) {
|
|
return arg;
|
|
}
|
|
|
|
bool NativeCxxModuleExample::getBool(jsi::Runtime &rt, bool arg) {
|
|
return arg;
|
|
}
|
|
|
|
ConstantsStruct NativeCxxModuleExample::getConstants(jsi::Runtime &rt) {
|
|
return ConstantsStruct{true, 69, "react-native"};
|
|
}
|
|
|
|
CustomEnumInt NativeCxxModuleExample::getCustomEnum(
|
|
jsi::Runtime &rt,
|
|
CustomEnumInt arg) {
|
|
return arg;
|
|
}
|
|
|
|
NativeCxxModuleExampleCxxEnumFloat NativeCxxModuleExample::getNumEnum(
|
|
jsi::Runtime &rt,
|
|
NativeCxxModuleExampleCxxEnumInt arg) {
|
|
return NativeCxxModuleExampleCxxEnumFloat::FB;
|
|
}
|
|
|
|
NativeCxxModuleExampleCxxEnumStr NativeCxxModuleExample::getStrEnum(
|
|
jsi::Runtime &rt,
|
|
NativeCxxModuleExampleCxxEnumNone arg) {
|
|
return NativeCxxModuleExampleCxxEnumStr::SB;
|
|
}
|
|
|
|
std::map<std::string, std::optional<int32_t>> NativeCxxModuleExample::getMap(
|
|
jsi::Runtime &rt,
|
|
std::map<std::string, std::optional<int32_t>> arg) {
|
|
return arg;
|
|
}
|
|
|
|
double NativeCxxModuleExample::getNumber(jsi::Runtime &rt, double arg) {
|
|
return arg;
|
|
}
|
|
|
|
ObjectStruct NativeCxxModuleExample::getObject(
|
|
jsi::Runtime &rt,
|
|
ObjectStruct arg) {
|
|
return arg;
|
|
}
|
|
|
|
std::set<float> NativeCxxModuleExample::getSet(
|
|
jsi::Runtime &rt,
|
|
std::set<float> arg) {
|
|
return arg;
|
|
}
|
|
|
|
std::string NativeCxxModuleExample::getString(
|
|
jsi::Runtime &rt,
|
|
std::string arg) {
|
|
return arg;
|
|
}
|
|
|
|
std::string NativeCxxModuleExample::getUnion(
|
|
jsi::Runtime &rt,
|
|
float x,
|
|
std::string y,
|
|
jsi::Object z) {
|
|
std::string result = "x: " + std::to_string(x) + ", y: " + y + ", z: { ";
|
|
if (z.hasProperty(rt, "value")) {
|
|
result += "value: ";
|
|
result += std::to_string(z.getProperty(rt, "value").getNumber());
|
|
} else if (z.hasProperty(rt, "low")) {
|
|
result += "low: ";
|
|
result += z.getProperty(rt, "low").getString(rt).utf8(rt);
|
|
}
|
|
result += " }";
|
|
return result;
|
|
}
|
|
|
|
ValueStruct NativeCxxModuleExample::getValue(
|
|
jsi::Runtime &rt,
|
|
double x,
|
|
std::string y,
|
|
ObjectStruct z) {
|
|
ValueStruct result{x, y, z};
|
|
return result;
|
|
}
|
|
|
|
AsyncPromise<std::string> NativeCxxModuleExample::getValueWithPromise(
|
|
jsi::Runtime &rt,
|
|
bool error) {
|
|
auto promise = AsyncPromise<std::string>(rt, jsInvoker_);
|
|
if (error) {
|
|
promise.reject("intentional promise rejection");
|
|
} else {
|
|
promise.resolve("result!");
|
|
}
|
|
return promise;
|
|
}
|
|
|
|
std::optional<bool> NativeCxxModuleExample::getWithWithOptionalArgs(
|
|
jsi::Runtime &rt,
|
|
std::optional<bool> optionalArg) {
|
|
return optionalArg;
|
|
}
|
|
|
|
void NativeCxxModuleExample::voidFunc(jsi::Runtime &rt) {
|
|
// Nothing to do
|
|
}
|
|
|
|
void NativeCxxModuleExample::emitCustomDeviceEvent(
|
|
jsi::Runtime &rt,
|
|
jsi::String eventName) {
|
|
// Test emitting device events (RCTDeviceEventEmitter.emit) from C++
|
|
// TurboModule with arbitrary arguments
|
|
emitDeviceEvent(
|
|
rt,
|
|
eventName.utf8(rt).c_str(),
|
|
[](jsi::Runtime &rt, std::vector<jsi::Value> &args) {
|
|
args.emplace_back(jsi::Value(true));
|
|
args.emplace_back(jsi::Value(42));
|
|
args.emplace_back(jsi::String::createFromAscii(rt, "stringArg"));
|
|
});
|
|
}
|
|
|
|
void NativeCxxModuleExample::voidFuncThrows(jsi::Runtime &rt) {
|
|
throw std::runtime_error("Intentional exception from Cxx voidFuncThrows");
|
|
};
|
|
|
|
ObjectStruct NativeCxxModuleExample::getObjectThrows(
|
|
jsi::Runtime &rt,
|
|
ObjectStruct arg) {
|
|
throw std::runtime_error("Intentional exception from Cxx getObjectThrows");
|
|
};
|
|
|
|
AsyncPromise<jsi::Value> NativeCxxModuleExample::promiseThrows(
|
|
jsi::Runtime &rt) {
|
|
throw std::runtime_error("Intentional exception from Cxx promiseThrows");
|
|
};
|
|
|
|
void NativeCxxModuleExample::voidFuncAssert(jsi::Runtime &rt) {
|
|
react_native_assert(false && "Intentional assert from Cxx voidFuncAssert");
|
|
};
|
|
|
|
ObjectStruct NativeCxxModuleExample::getObjectAssert(
|
|
jsi::Runtime &rt,
|
|
ObjectStruct arg) {
|
|
react_native_assert(false && "Intentional assert from Cxx getObjectAssert");
|
|
|
|
// Asserts disabled
|
|
return {};
|
|
};
|
|
|
|
AsyncPromise<jsi::Value> NativeCxxModuleExample::promiseAssert(
|
|
jsi::Runtime &rt) {
|
|
react_native_assert(false && "Intentional assert from Cxx promiseAssert");
|
|
|
|
// Asserts disabled
|
|
auto promise = AsyncPromise<jsi::Value>(rt, jsInvoker_);
|
|
promise.reject("Asserts disabled");
|
|
return promise;
|
|
};
|
|
|
|
} // namespace facebook::react
|