diff --git a/ReactCommon/react/renderer/core/RawValue.h b/ReactCommon/react/renderer/core/RawValue.h index d541f11a16ed9d..c69f9e43ceacde 100644 --- a/ReactCommon/react/renderer/core/RawValue.h +++ b/ReactCommon/react/renderer/core/RawValue.h @@ -96,7 +96,7 @@ class RawValue { * Casts the value to a specified type. */ template - explicit operator T() const noexcept { + explicit operator T() const { return castValue(dynamic_, (T *)nullptr); } @@ -212,40 +212,36 @@ class RawValue { return RawValue(dynamic); } - static bool castValue(const folly::dynamic &dynamic, bool *type) noexcept { + static bool castValue(const folly::dynamic &dynamic, bool *type) { return dynamic.getBool(); } - static int castValue(const folly::dynamic &dynamic, int *type) noexcept { + static int castValue(const folly::dynamic &dynamic, int *type) { return static_cast(dynamic.asInt()); } - static int64_t castValue( - const folly::dynamic &dynamic, - int64_t *type) noexcept { + static int64_t castValue(const folly::dynamic &dynamic, int64_t *type) { return dynamic.asInt(); } - static float castValue(const folly::dynamic &dynamic, float *type) noexcept { + static float castValue(const folly::dynamic &dynamic, float *type) { return static_cast(dynamic.asDouble()); } - static double castValue( - const folly::dynamic &dynamic, - double *type) noexcept { + static double castValue(const folly::dynamic &dynamic, double *type) { return dynamic.asDouble(); } static std::string castValue( const folly::dynamic &dynamic, - std::string *type) noexcept { + std::string *type) { return dynamic.getString(); } template static std::vector castValue( const folly::dynamic &dynamic, - std::vector *type) noexcept { + std::vector *type) { react_native_assert(dynamic.isArray()); auto result = std::vector{}; result.reserve(dynamic.size()); @@ -258,7 +254,7 @@ class RawValue { template static std::vector> castValue( const folly::dynamic &dynamic, - std::vector> *type) noexcept { + std::vector> *type) { react_native_assert(dynamic.isArray()); auto result = std::vector>{}; result.reserve(dynamic.size()); @@ -271,7 +267,7 @@ class RawValue { template static butter::map castValue( const folly::dynamic &dynamic, - butter::map *type) noexcept { + butter::map *type) { react_native_assert(dynamic.isObject()); auto result = butter::map{}; for (const auto &item : dynamic.items()) { diff --git a/ReactCommon/react/renderer/core/propsConversions.h b/ReactCommon/react/renderer/core/propsConversions.h index adbc07860736a0..c4221f977567f9 100644 --- a/ReactCommon/react/renderer/core/propsConversions.h +++ b/ReactCommon/react/renderer/core/propsConversions.h @@ -10,9 +10,9 @@ #include #include -#include #include #include +#include #include #include #include @@ -43,18 +43,18 @@ template void fromRawValue( const PropsParserContext &context, RawValue const &rawValue, - std::optional &result) { - T res{}; - fromRawValue(context, rawValue, res); - result = std::optional(res); + T &result) { + result = (T)rawValue; } template void fromRawValue( const PropsParserContext &context, RawValue const &rawValue, - T &result) { - result = (T)rawValue; + std::optional &result) { + T resultValue; + fromRawValue(context, rawValue, resultValue); + result = std::optional{std::move(resultValue)}; } template @@ -119,7 +119,6 @@ T convertRawProp( char const *namePrefix = nullptr, char const *nameSuffix = nullptr) { const auto *rawValue = rawProps.at(name, namePrefix, nameSuffix); - if (LIKELY(rawValue == nullptr)) { return sourceValue; } @@ -130,35 +129,18 @@ T convertRawProp( return defaultValue; } - T result; - fromRawValue(context, *rawValue, result); - return result; -} - -template -static std::optional convertRawProp( - const PropsParserContext &context, - RawProps const &rawProps, - char const *name, - std::optional const &sourceValue, - std::optional const &defaultValue, - char const *namePrefix = nullptr, - char const *nameSuffix = nullptr) { - const auto *rawValue = rawProps.at(name, namePrefix, nameSuffix); - - if (LIKELY(rawValue == nullptr)) { - return sourceValue; - } - - // Special case: `null` always means `the prop was removed, use default - // value`. - if (UNLIKELY(!rawValue->hasValue())) { + try { + T result; + fromRawValue(context, *rawValue, result); + return result; + } catch (const std::exception &e) { + // In case of errors, log the error and fall back to the default + RawPropsKey key{namePrefix, name, nameSuffix}; + // TODO: report this using ErrorUtils so it's more visible to the user + LOG(ERROR) << "Error while converting prop '" + << static_cast(key) << "': " << e.what(); return defaultValue; } - - T result; - fromRawValue(context, *rawValue, result); - return std::optional{result}; } } // namespace react