The below code is somewhat malformed, as DefaultIfMissing's default value does not match what the validator expects. In these cases, IMO, it is fine to throw an exception. The library seems wrap potentially throwing code in a noexcept function.
Code to reproduce the issue:
#include <rfl.hpp>
#include <rfl/json.hpp>
using namespace std::literals;
constexpr auto data = R"({"str": "asdfasdf"})"sv;
using Str = rfl::Validator<std::string, rfl::Size<rfl::Minimum<1>>,
rfl::Size<rfl::Maximum<100>>>;
struct Sample {
Str str;
};
int main() {
try {
auto res = rfl::json::read<Sample, rfl::DefaultIfMissing>(data);
} catch (const std::exception& e) {
std::cerr << "ERROR: " << e.what() << '\n';
}
}
Output:
terminate called after throwing an instance of 'std::runtime_error'
what(): Size validation failed: Value expected to be greater than or equal to 1, but got 0.
Aborted (core dumped)
The fix seems quite trivial:
diff --git a/include/rfl/AllOf.hpp b/include/rfl/AllOf.hpp
index ca25c88..b158e30 100644
--- a/include/rfl/AllOf.hpp
+++ b/include/rfl/AllOf.hpp
@@ -15,7 +15,7 @@ struct AllOf {
/// @param _value The value to validate
/// @return The value if all constraints pass, otherwise an error
template <class T>
- static rfl::Result<T> validate(T _value) noexcept {
+ static rfl::Result<T> validate(T _value) {
return validate_impl<T, C, Cs...>(_value);
}
@@ -31,7 +31,7 @@ struct AllOf {
private:
template <class T, class Head, class... Tail>
- static rfl::Result<T> validate_impl(T _value) noexcept {
+ static rfl::Result<T> validate_impl(T _value) {
if constexpr (sizeof...(Tail) == 0) {
return Head::validate(_value);
} else {
diff --git a/include/rfl/parsing/Parser_default.hpp b/include/rfl/parsing/Parser_default.hpp
index b7de7f7..725cff7 100644
--- a/include/rfl/parsing/Parser_default.hpp
+++ b/include/rfl/parsing/Parser_default.hpp
@@ -51,7 +51,7 @@ struct Parser {
* @param _var The input variable to read from.
* @return A Result containing the parsed value or an error.
*/
- static Result<T> read(const R& _r, const InputVarType& _var) noexcept {
+ static Result<T> read(const R& _r, const InputVarType& _var) {
if constexpr (internal::has_read_reflector<T>) {
const auto wrap_in_t = [](auto&& _named_tuple) -> Result<T> {
try {
The below code is somewhat malformed, as
DefaultIfMissing's default value does not match what the validator expects. In these cases, IMO, it is fine to throw an exception. The library seems wrap potentially throwing code in anoexceptfunction.Code to reproduce the issue:
Output:
The fix seems quite trivial: