From 686da820d6de72e232e8b6171bcba83b9405e1c8 Mon Sep 17 00:00:00 2001 From: Lookingforcommit Date: Mon, 20 Jan 2025 20:33:19 +0300 Subject: [PATCH] [chaotic] exceptions should not depend on json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parametrized chaotic exceptions with typename value. Chaotic validators now throw exceptions derived from formats::Value::Exception Tests: протестировано CI Pull Request resolved: https://github.com/userver-framework/userver/pull/825 commit_hash:27cf69ecf852ecca12ac6c840a22f6524929d3c7 --- chaotic/include/userver/chaotic/exception.hpp | 7 ++-- chaotic/include/userver/chaotic/object.hpp | 3 +- chaotic/integration_tests/tests/lib/array.cpp | 5 ++- .../integration_tests/tests/lib/primitive.cpp | 34 +++++++++++++++---- .../integration_tests/tests/render/minmax.cpp | 22 ++++++++---- .../integration_tests/tests/render/simple.cpp | 20 +++++++---- 6 files changed, 67 insertions(+), 24 deletions(-) diff --git a/chaotic/include/userver/chaotic/exception.hpp b/chaotic/include/userver/chaotic/exception.hpp index 151fec300c91..b8363e18b952 100644 --- a/chaotic/include/userver/chaotic/exception.hpp +++ b/chaotic/include/userver/chaotic/exception.hpp @@ -10,13 +10,14 @@ USERVER_NAMESPACE_BEGIN namespace chaotic { -class Error final : public formats::json::Exception { - using Exception::Exception; +template +class Error final : public Value::Exception { + using Value::Exception::Exception; }; template [[noreturn]] inline void ThrowForValue(std::string_view str, Value value) { - throw Error(fmt::format("Error at path '{}': {}", value.GetPath(), str)); + throw Error(fmt::format("Error at path '{}': {}", value.GetPath(), str)); } } // namespace chaotic diff --git a/chaotic/include/userver/chaotic/object.hpp b/chaotic/include/userver/chaotic/object.hpp index ceeb810fd25e..f5559ac05a07 100644 --- a/chaotic/include/userver/chaotic/object.hpp +++ b/chaotic/include/userver/chaotic/object.hpp @@ -5,6 +5,7 @@ #include +#include #include #include #include @@ -30,7 +31,7 @@ void ValidateNoAdditionalProperties(const Value& json, const utils::TrivialSet(fmt::format("Unknown property '{}'", name)); } } diff --git a/chaotic/integration_tests/tests/lib/array.cpp b/chaotic/integration_tests/tests/lib/array.cpp index dd4d4fd7667f..1ea11be7f511 100644 --- a/chaotic/integration_tests/tests/lib/array.cpp +++ b/chaotic/integration_tests/tests/lib/array.cpp @@ -7,6 +7,7 @@ #include #include #include +#include USERVER_NAMESPACE_BEGIN @@ -37,7 +38,9 @@ TEST(Array, OfIntWithValidators) { const auto kJson1 = formats::json::MakeArray("foo"); UEXPECT_THROW_MSG( - kJson1.As(), chaotic::Error, "Error at path '/': Too short array, minimum length=2, given=1" + kJson1.As(), + chaotic::Error, + "Error at path '/': Too short array, minimum length=2, given=1" ); } diff --git a/chaotic/integration_tests/tests/lib/primitive.cpp b/chaotic/integration_tests/tests/lib/primitive.cpp index b5aa22877065..96b2355acd48 100644 --- a/chaotic/integration_tests/tests/lib/primitive.cpp +++ b/chaotic/integration_tests/tests/lib/primitive.cpp @@ -69,8 +69,16 @@ TEST(Primitive, IntMinMax) { int x = kJson["foo"].As(); EXPECT_EQ(x, 1); - UEXPECT_THROW_MSG(kJson["bar"].As(), chaotic::Error, "Error at path 'bar': Invalid value, minimum=1, given=0"); - UEXPECT_THROW_MSG(kJson["zoo"].As(), chaotic::Error, "Error at path 'zoo': Invalid value, maximum=5, given=6"); + UEXPECT_THROW_MSG( + kJson["bar"].As(), + chaotic::Error, + "Error at path 'bar': Invalid value, minimum=1, given=0" + ); + UEXPECT_THROW_MSG( + kJson["zoo"].As(), + chaotic::Error, + "Error at path 'zoo': Invalid value, maximum=5, given=6" + ); } TEST(Primitive, UserTypeMinMax) { @@ -80,8 +88,16 @@ TEST(Primitive, UserTypeMinMax) { MyInt x = kJson["foo"].As(); EXPECT_EQ(x.value, 1); - UEXPECT_THROW_MSG(kJson["bar"].As(), chaotic::Error, "Error at path 'bar': Invalid value, minimum=1, given=0"); - UEXPECT_THROW_MSG(kJson["zoo"].As(), chaotic::Error, "Error at path 'zoo': Invalid value, maximum=5, given=6"); + UEXPECT_THROW_MSG( + kJson["bar"].As(), + chaotic::Error, + "Error at path 'bar': Invalid value, minimum=1, given=0" + ); + UEXPECT_THROW_MSG( + kJson["zoo"].As(), + chaotic::Error, + "Error at path 'zoo': Invalid value, maximum=5, given=6" + ); } TEST(Primitive, StringMinMaxLength) { @@ -93,10 +109,14 @@ TEST(Primitive, StringMinMaxLength) { EXPECT_EQ(x, "12"); UEXPECT_THROW_MSG( - kLocalJson["1"].As(), chaotic::Error, "Error at path '1': Too short string, minimum length=2, given=1" + kLocalJson["1"].As(), + chaotic::Error, + "Error at path '1': Too short string, minimum length=2, given=1" ); UEXPECT_THROW_MSG( - kLocalJson["6"].As(), chaotic::Error, "Error at path '6': Too long string, maximum length=5, given=6" + kLocalJson["6"].As(), + chaotic::Error, + "Error at path '6': Too long string, maximum length=5, given=6" ); } @@ -110,7 +130,7 @@ TEST(Primitive, StringPattern) { std::string x = kLocalJson["1"].As(); EXPECT_EQ(x, "foo"); - UEXPECT_THROW_MSG(kLocalJson["2"].As(), chaotic::Error, "doesn't match regex"); + UEXPECT_THROW_MSG(kLocalJson["2"].As(), chaotic::Error, "doesn't match regex"); } USERVER_NAMESPACE_END diff --git a/chaotic/integration_tests/tests/render/minmax.cpp b/chaotic/integration_tests/tests/render/minmax.cpp index 969f92778ccf..ed11fa4627b6 100644 --- a/chaotic/integration_tests/tests/render/minmax.cpp +++ b/chaotic/integration_tests/tests/render/minmax.cpp @@ -10,7 +10,9 @@ USERVER_NAMESPACE_BEGIN TEST(MinMax, ExclusiveInt) { auto json = formats::json::MakeObject("foo", 1); UEXPECT_THROW_MSG( - json.As(), chaotic::Error, "Error at path 'foo': Invalid value, exclusive minimum=1, given=1" + json.As(), + chaotic::Error, + "Error at path 'foo': Invalid value, exclusive minimum=1, given=1" ); json = formats::json::MakeObject("foo", 2); @@ -19,7 +21,7 @@ TEST(MinMax, ExclusiveInt) { json = formats::json::MakeObject("foo", 20); UEXPECT_THROW_MSG( json.As(), - chaotic::Error, + chaotic::Error, "Error at path 'foo': Invalid value, exclusive maximum=20, given=20" ); @@ -30,24 +32,32 @@ TEST(MinMax, ExclusiveInt) { TEST(MinMax, String) { auto json = formats::json::MakeObject("bar", ""); UEXPECT_THROW_MSG( - json.As(), chaotic::Error, "Error at path 'bar': Too short string, minimum length=2, given=0" + json.As(), + chaotic::Error, + "Error at path 'bar': Too short string, minimum length=2, given=0" ); json = formats::json::MakeObject("bar", "longlonglong"); UEXPECT_THROW_MSG( - json.As(), chaotic::Error, "Error at path 'bar': Too long string, maximum length=5, given=12" + json.As(), + chaotic::Error, + "Error at path 'bar': Too long string, maximum length=5, given=12" ); } TEST(MinMax, Array) { auto json = formats::json::MakeObject("zoo", formats::json::MakeArray(1)); UEXPECT_THROW_MSG( - json.As(), chaotic::Error, "Error at path 'zoo': Too short array, minimum length=2, given=1" + json.As(), + chaotic::Error, + "Error at path 'zoo': Too short array, minimum length=2, given=1" ); json = formats::json::MakeObject("zoo", formats::json::MakeArray(1, 2, 3, 4, 5, 6, 7, 8)); UEXPECT_THROW_MSG( - json.As(), chaotic::Error, "Error at path 'zoo': Too long array, maximum length=5, given=8" + json.As(), + chaotic::Error, + "Error at path 'zoo': Too long array, maximum length=5, given=8" ); } diff --git a/chaotic/integration_tests/tests/render/simple.cpp b/chaotic/integration_tests/tests/render/simple.cpp index f0bdb9f859fd..f511705a3ffa 100644 --- a/chaotic/integration_tests/tests/render/simple.cpp +++ b/chaotic/integration_tests/tests/render/simple.cpp @@ -45,14 +45,18 @@ TEST(Simple, DefaultFieldValue) { TEST(Simple, IntegerMinimum) { auto json = formats::json::MakeObject("int3", 1, "int", -10); UEXPECT_THROW_MSG( - json.As(), chaotic::Error, "Error at path 'int': Invalid value, minimum=-1, given=-10" + json.As(), + chaotic::Error, + "Error at path 'int': Invalid value, minimum=-1, given=-10" ); } TEST(Simple, IntegerMaximum) { auto json = formats::json::MakeObject("int3", 1, "int", 11); UEXPECT_THROW_MSG( - json.As(), chaotic::Error, "Error at path 'int': Invalid value, maximum=10, given=11" + json.As(), + chaotic::Error, + "Error at path 'int': Invalid value, maximum=10, given=11" ); } @@ -78,7 +82,9 @@ TEST(Simple, IntegerFormat) { TEST(Simple, ObjectWithRefType) { auto json = formats::json::MakeObject("integer", 0); UEXPECT_THROW_MSG( - json.As(), chaotic::Error, "Error at path 'integer': Invalid value, minimum=1, given=0" + json.As(), + chaotic::Error, + "Error at path 'integer': Invalid value, minimum=1, given=0" ); } @@ -141,7 +147,9 @@ TEST(Simple, ObjectExtraMemberFalse) { TEST(Simple, ObjectWithAdditionalPropertiesFalseStrict) { auto json = formats::json::MakeObject("foo", 1, "bar", 2); UEXPECT_THROW_MSG( - json.As(), std::runtime_error, "Unknown property 'bar'" + json.As(), + chaotic::Error, + "Unknown property 'bar'" ); } @@ -156,7 +164,7 @@ TEST(Simple, IntegerEnum) { auto json2 = formats::json::MakeObject("one", 5); UEXPECT_THROW_MSG( json2["one"].As(), - chaotic::Error, + chaotic::Error, "Error at path 'one': Invalid enum value (5) for type ns::IntegerEnum" ); @@ -181,7 +189,7 @@ TEST(Simple, StringEnum) { auto json2 = formats::json::MakeObject("one", "zoo"); UEXPECT_THROW_MSG( json2["one"].As(), - chaotic::Error, + chaotic::Error, "Error at path 'one': Invalid enum value (zoo) for type ns::StringEnum" );