diff options
author | ThiƩbaud Weksteen <tweek@google.com> | 2020-10-26 15:44:13 +0100 |
---|---|---|
committer | ThiƩbaud Weksteen <tweek@google.com> | 2020-10-26 15:54:14 +0100 |
commit | f5397480a691df4997c9b12400957874df7dc460 (patch) | |
tree | 6f0c652eaed9c821dd1656ecce4ebca04c99cec2 /libjsonpb | |
parent | 7ebc9e6cd61d5b167ccccbea85f42387370f51a7 (diff) | |
download | extras-f5397480a691df4997c9b12400957874df7dc460.tar.gz |
libjsonpb: format files
Format *.cpp according to the new .clang-format-2. The following command
was used to generate this change:
$ find . \( -name \*.cpp -o -name \*.h \) -exec clang-format \
--style=file -i {} \;
Test: mm
Bug: 171699326
Change-Id: I7f1199fd8a3431500484f7373ccb5f1583a00956
Diffstat (limited to 'libjsonpb')
l--------- | libjsonpb/.clang-format | 1 | ||||
-rw-r--r-- | libjsonpb/parse/include/jsonpb/error_or.h | 67 | ||||
-rw-r--r-- | libjsonpb/parse/include/jsonpb/jsonpb.h | 13 | ||||
-rw-r--r-- | libjsonpb/parse/jsonpb.cpp | 46 | ||||
-rw-r--r-- | libjsonpb/verify/include/jsonpb/json_schema_test.h | 29 | ||||
-rw-r--r-- | libjsonpb/verify/include/jsonpb/verify.h | 11 | ||||
-rw-r--r-- | libjsonpb/verify/test.cpp | 52 | ||||
-rw-r--r-- | libjsonpb/verify/verify.cpp | 41 |
8 files changed, 110 insertions, 150 deletions
diff --git a/libjsonpb/.clang-format b/libjsonpb/.clang-format new file mode 120000 index 00000000..fd0645fd --- /dev/null +++ b/libjsonpb/.clang-format @@ -0,0 +1 @@ +../.clang-format-2
\ No newline at end of file diff --git a/libjsonpb/parse/include/jsonpb/error_or.h b/libjsonpb/parse/include/jsonpb/error_or.h index 66e22969..3fd3e997 100644 --- a/libjsonpb/parse/include/jsonpb/error_or.h +++ b/libjsonpb/parse/include/jsonpb/error_or.h @@ -14,7 +14,6 @@ * limitations under the License. */ - #pragma once #include <string> @@ -27,45 +26,45 @@ namespace jsonpb { template <typename T> struct ErrorOr { - template <class... Args> - explicit ErrorOr(Args&&... args) : data_(kIndex1, std::forward<Args>(args)...) {} - T& operator*() { - CHECK(ok()); - return *std::get_if<1u>(&data_); - } - const T& operator*() const { - CHECK(ok()); - return *std::get_if<1u>(&data_); - } - T* operator->() { - CHECK(ok()); - return std::get_if<1u>(&data_); - } - const T* operator->() const { - CHECK(ok()); - return std::get_if<1u>(&data_); - } - const std::string& error() const { - CHECK(!ok()); - return *std::get_if<0u>(&data_); - } - bool ok() const { return data_.index() != 0; } - static ErrorOr<T> MakeError(const std::string& message) { - return ErrorOr<T>(message, Tag::kDummy); - } + template <class... Args> + explicit ErrorOr(Args&&... args) : data_(kIndex1, std::forward<Args>(args)...) {} + T& operator*() { + CHECK(ok()); + return *std::get_if<1u>(&data_); + } + const T& operator*() const { + CHECK(ok()); + return *std::get_if<1u>(&data_); + } + T* operator->() { + CHECK(ok()); + return std::get_if<1u>(&data_); + } + const T* operator->() const { + CHECK(ok()); + return std::get_if<1u>(&data_); + } + const std::string& error() const { + CHECK(!ok()); + return *std::get_if<0u>(&data_); + } + bool ok() const { return data_.index() != 0; } + static ErrorOr<T> MakeError(const std::string& message) { + return ErrorOr<T>(message, Tag::kDummy); + } - private: - enum class Tag { kDummy }; - static constexpr std::in_place_index_t<0> kIndex0{}; - static constexpr std::in_place_index_t<1> kIndex1{}; - ErrorOr(const std::string& msg, Tag) : data_(kIndex0, msg) {} + private: + enum class Tag { kDummy }; + static constexpr std::in_place_index_t<0> kIndex0{}; + static constexpr std::in_place_index_t<1> kIndex1{}; + ErrorOr(const std::string& msg, Tag) : data_(kIndex0, msg) {} - std::variant<std::string, T> data_; + std::variant<std::string, T> data_; }; template <typename T> inline ErrorOr<T> MakeError(const std::string& message) { - return ErrorOr<T>::MakeError(message); + return ErrorOr<T>::MakeError(message); } } // namespace jsonpb diff --git a/libjsonpb/parse/include/jsonpb/jsonpb.h b/libjsonpb/parse/include/jsonpb/jsonpb.h index 350db7fb..0b91a220 100644 --- a/libjsonpb/parse/include/jsonpb/jsonpb.h +++ b/libjsonpb/parse/include/jsonpb/jsonpb.h @@ -14,7 +14,6 @@ * limitations under the License. */ - #pragma once #include <string> @@ -37,12 +36,12 @@ ErrorOr<std::monostate> JsonStringToMessage(const std::string& content, // when the android tree gets updated template <typename T> ErrorOr<T> JsonStringToMessage(const std::string& content) { - ErrorOr<T> ret; - auto error = internal::JsonStringToMessage(content, &*ret); - if (!error.ok()) { - return MakeError<T>(error.error()); - } - return ret; + ErrorOr<T> ret; + auto error = internal::JsonStringToMessage(content, &*ret); + if (!error.ok()) { + return MakeError<T>(error.error()); + } + return ret; } // TODO: MessageToJsonString is a newly added function in protobuf diff --git a/libjsonpb/parse/jsonpb.cpp b/libjsonpb/parse/jsonpb.cpp index d7feb670..3a042e71 100644 --- a/libjsonpb/parse/jsonpb.cpp +++ b/libjsonpb/parse/jsonpb.cpp @@ -33,40 +33,40 @@ using google::protobuf::util::TypeResolver; static constexpr char kTypeUrlPrefix[] = "type.googleapis.com"; std::string GetTypeUrl(const Message& message) { - return std::string(kTypeUrlPrefix) + "/" + message.GetDescriptor()->full_name(); + return std::string(kTypeUrlPrefix) + "/" + message.GetDescriptor()->full_name(); } ErrorOr<std::string> MessageToJsonString(const Message& message) { - std::unique_ptr<TypeResolver> resolver( - NewTypeResolverForDescriptorPool(kTypeUrlPrefix, DescriptorPool::generated_pool())); + std::unique_ptr<TypeResolver> resolver( + NewTypeResolverForDescriptorPool(kTypeUrlPrefix, DescriptorPool::generated_pool())); - google::protobuf::util::JsonOptions options; - options.add_whitespace = true; + google::protobuf::util::JsonOptions options; + options.add_whitespace = true; - std::string json; - auto status = BinaryToJsonString(resolver.get(), GetTypeUrl(message), - message.SerializeAsString(), &json, options); + std::string json; + auto status = BinaryToJsonString(resolver.get(), GetTypeUrl(message), message.SerializeAsString(), + &json, options); - if (!status.ok()) { - return MakeError<std::string>(status.error_message().as_string()); - } - return ErrorOr<std::string>(std::move(json)); + if (!status.ok()) { + return MakeError<std::string>(status.error_message().as_string()); + } + return ErrorOr<std::string>(std::move(json)); } namespace internal { ErrorOr<std::monostate> JsonStringToMessage(const std::string& content, Message* message) { - std::unique_ptr<TypeResolver> resolver( - NewTypeResolverForDescriptorPool(kTypeUrlPrefix, DescriptorPool::generated_pool())); + std::unique_ptr<TypeResolver> resolver( + NewTypeResolverForDescriptorPool(kTypeUrlPrefix, DescriptorPool::generated_pool())); - std::string binary; - auto status = JsonToBinaryString(resolver.get(), GetTypeUrl(*message), content, &binary); - if (!status.ok()) { - return MakeError<std::monostate>(status.error_message().as_string()); - } - if (!message->ParseFromString(binary)) { - return MakeError<std::monostate>("Fail to parse."); - } - return ErrorOr<std::monostate>(); + std::string binary; + auto status = JsonToBinaryString(resolver.get(), GetTypeUrl(*message), content, &binary); + if (!status.ok()) { + return MakeError<std::monostate>(status.error_message().as_string()); + } + if (!message->ParseFromString(binary)) { + return MakeError<std::monostate>("Fail to parse."); + } + return ErrorOr<std::monostate>(); } } // namespace internal diff --git a/libjsonpb/verify/include/jsonpb/json_schema_test.h b/libjsonpb/verify/include/jsonpb/json_schema_test.h index 3db19310..6fa834b2 100644 --- a/libjsonpb/verify/include/jsonpb/json_schema_test.h +++ b/libjsonpb/verify/include/jsonpb/json_schema_test.h @@ -14,7 +14,6 @@ * limitations under the License. */ - #pragma once #include <unistd.h> @@ -46,12 +45,9 @@ class JsonSchemaTestConfig { /** * If it returns true, tests are skipped when the file is not found. */ - virtual bool optional() const { - return false; - } + virtual bool optional() const { return false; } }; -using JsonSchemaTestConfigFactory = - std::function<std::unique_ptr<JsonSchemaTestConfig>()>; +using JsonSchemaTestConfigFactory = std::function<std::unique_ptr<JsonSchemaTestConfig>()>; template <typename T> class AbstractJsonSchemaTestConfig : public JsonSchemaTestConfig { @@ -68,22 +64,18 @@ class AbstractJsonSchemaTestConfig : public JsonSchemaTestConfig { template <typename T> JsonSchemaTestConfigFactory MakeTestParam(const std::string& path) { - return [path]() { - return std::make_unique<AbstractJsonSchemaTestConfig<T>>(path); - }; + return [path]() { return std::make_unique<AbstractJsonSchemaTestConfig<T>>(path); }; } -class JsonSchemaTest - : public ::testing::TestWithParam<JsonSchemaTestConfigFactory> { +class JsonSchemaTest : public ::testing::TestWithParam<JsonSchemaTestConfigFactory> { public: void SetUp() override { - auto&& config = - ::testing::TestWithParam<JsonSchemaTestConfigFactory>::GetParam()(); + auto&& config = ::testing::TestWithParam<JsonSchemaTestConfigFactory>::GetParam()(); file_path_ = config->file_path(); if (access(file_path_.c_str(), F_OK) == -1) { - ASSERT_EQ(ENOENT, errno) << "File '" << file_path_ << "' is not accessible: " - << strerror(errno); + ASSERT_EQ(ENOENT, errno) << "File '" << file_path_ + << "' is not accessible: " << strerror(errno); ASSERT_TRUE(config->optional()) << "Missing mandatory file " << file_path_; GTEST_SKIP(); } @@ -92,12 +84,9 @@ class JsonSchemaTest object_ = config->CreateMessage(); auto res = internal::JsonStringToMessage(json_, object_.get()); - ASSERT_TRUE(res.ok()) << "Invalid format of file " << file_path_ - << ": " << res.error(); - } - google::protobuf::Message* message() const { - return object_.get(); + ASSERT_TRUE(res.ok()) << "Invalid format of file " << file_path_ << ": " << res.error(); } + google::protobuf::Message* message() const { return object_.get(); } std::string file_path_; std::string json_; std::unique_ptr<google::protobuf::Message> object_; diff --git a/libjsonpb/verify/include/jsonpb/verify.h b/libjsonpb/verify/include/jsonpb/verify.h index c05b13d2..bb247e7e 100644 --- a/libjsonpb/verify/include/jsonpb/verify.h +++ b/libjsonpb/verify/include/jsonpb/verify.h @@ -14,7 +14,6 @@ * limitations under the License. */ - #pragma once #include <sstream> @@ -64,8 +63,8 @@ namespace jsonpb { // path: path to navigate inside JSON tree. For example, {"foo", "bar"} for // the value "string" in // {"foo": {"bar" : "string"}} -bool AllFieldsAreKnown(const google::protobuf::Message& message, - const std::string& json, std::string* error); +bool AllFieldsAreKnown(const google::protobuf::Message& message, const std::string& json, + std::string* error); // Format the given JSON string according to Prototype T. This will serialize // the JSON string to a Prototype message, then re-print the message as JSON. By @@ -78,14 +77,12 @@ bool AllFieldsAreKnown(const google::protobuf::Message& message, // scratch_space: The scratch space to use to store the Protobuf message. It // must be a pointer // to the schema that the JSON string conforms to. -bool EqReformattedJson(const std::string& json, - google::protobuf::Message* scratch_space, +bool EqReformattedJson(const std::string& json, google::protobuf::Message* scratch_space, std::string* error); namespace internal { // See EqReformattedJson(). -ErrorOr<std::string> FormatJson(const std::string& json, - google::protobuf::Message* scratch_space); +ErrorOr<std::string> FormatJson(const std::string& json, google::protobuf::Message* scratch_space); } // namespace internal diff --git a/libjsonpb/verify/test.cpp b/libjsonpb/verify/test.cpp index cb98f47f..a430c134 100644 --- a/libjsonpb/verify/test.cpp +++ b/libjsonpb/verify/test.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ - #include <limits> #include <sstream> @@ -46,15 +45,12 @@ class JsonKeyTest : public LibJsonpbVerifyTest { } template <typename T> - void TestParseOkWithUnknownKey(const std::string& field_name, - const std::string& json_key) { + void TestParseOkWithUnknownKey(const std::string& field_name, const std::string& json_key) { std::string json = "{\"" + json_key + "\": \"test\"}"; auto object = JsonStringToMessage<T>(json); ASSERT_TRUE(object.ok()) << object.error(); - EXPECT_EQ( - "test", - object->GetReflection()->GetString( - *object, object->GetDescriptor()->FindFieldByName(field_name))); + EXPECT_EQ("test", object->GetReflection()->GetString( + *object, object->GetDescriptor()->FindFieldByName(field_name))); std::string error; ASSERT_FALSE(AllFieldsAreKnown(*object, json, &error)) << "AllFieldsAreKnown should return false"; @@ -148,8 +144,7 @@ TEST_F(JsonKeyTest, NoJsonNameQuxQuux) { class EmbeddedJsonKeyTest : public LibJsonpbVerifyTest { public: - ErrorOr<Parent> TestEmbeddedError(const std::string& json, - const std::string& unknown_key) { + ErrorOr<Parent> TestEmbeddedError(const std::string& json, const std::string& unknown_key) { auto object = JsonStringToMessage<Parent>(json); if (!object.ok()) return object; std::string error; @@ -184,30 +179,28 @@ TEST_F(EmbeddedJsonKeyTest, Ok) { } TEST_F(EmbeddedJsonKeyTest, FooBar) { - auto object = TestEmbeddedError( - "{\"with_json_name\": {\"foo_bar\": \"test\"}}", "foo_bar"); + auto object = TestEmbeddedError("{\"with_json_name\": {\"foo_bar\": \"test\"}}", "foo_bar"); ASSERT_TRUE(object.ok()) << object.error(); EXPECT_EQ("test", object->with_json_name().foo_bar()); } TEST_F(EmbeddedJsonKeyTest, BarBaz) { - auto object = TestEmbeddedError( - "{\"repeated_with_json_name\": [{\"barBaz\": \"test\"}]}", "barBaz"); + auto object = + TestEmbeddedError("{\"repeated_with_json_name\": [{\"barBaz\": \"test\"}]}", "barBaz"); ASSERT_TRUE(object.ok()) << object.error(); ASSERT_EQ(1u, object->repeated_with_json_name().size()); EXPECT_EQ("test", object->repeated_with_json_name().begin()->barbaz()); } TEST_F(EmbeddedJsonKeyTest, NoJsonName) { - auto object = TestEmbeddedError( - "{\"no_json_name\": {\"QUXQUUX\": \"test\"}}", "QUXQUUX"); + auto object = TestEmbeddedError("{\"no_json_name\": {\"QUXQUUX\": \"test\"}}", "QUXQUUX"); ASSERT_TRUE(object.ok()) << object.error(); EXPECT_EQ("test", object->no_json_name().qux_quux()); } TEST_F(EmbeddedJsonKeyTest, QuxQuux) { - auto object = TestEmbeddedError( - "{\"repeated_no_json_name\": [{\"QUXQUUX\": \"test\"}]}", "QUXQUUX"); + auto object = + TestEmbeddedError("{\"repeated_no_json_name\": [{\"QUXQUUX\": \"test\"}]}", "QUXQUUX"); ASSERT_TRUE(object.ok()) << object.error(); ASSERT_EQ(1u, object->repeated_no_json_name().size()); EXPECT_EQ("test", object->repeated_no_json_name().begin()->qux_quux()); @@ -215,24 +208,20 @@ TEST_F(EmbeddedJsonKeyTest, QuxQuux) { class ScalarTest : public LibJsonpbVerifyTest { public: - ::testing::AssertionResult IsJsonEq(const std::string& l, - const std::string& r) { + ::testing::AssertionResult IsJsonEq(const std::string& l, const std::string& r) { Json::Reader reader; Json::Value lvalue; if (!reader.parse(l, lvalue)) - return ::testing::AssertionFailure() - << reader.getFormattedErrorMessages(); + return ::testing::AssertionFailure() << reader.getFormattedErrorMessages(); Json::Value rvalue; if (!reader.parse(r, rvalue)) - return ::testing::AssertionFailure() - << reader.getFormattedErrorMessages(); + return ::testing::AssertionFailure() << reader.getFormattedErrorMessages(); Json::StyledWriter writer; return lvalue == rvalue ? (::testing::AssertionSuccess() << "Both are \n" << writer.write(lvalue)) - : (::testing::AssertionFailure() - << writer.write(lvalue) << "\n does not equal \n" - << writer.write(rvalue)); + : (::testing::AssertionFailure() << writer.write(lvalue) << "\n does not equal \n" + << writer.write(rvalue)); } bool EqReformattedJson(const std::string& json, std::string* error) { @@ -262,9 +251,8 @@ TEST_F(ScalarTest, Ok) { } using ScalarTestErrorParam = std::tuple<const char*, const char*>; -class ScalarTestError - : public ScalarTest, - public ::testing::WithParamInterface<ScalarTestErrorParam> {}; +class ScalarTestError : public ScalarTest, + public ::testing::WithParamInterface<ScalarTestErrorParam> {}; TEST_P(ScalarTestError, Test) { std::string json; @@ -273,8 +261,7 @@ TEST_P(ScalarTestError, Test) { auto formatted = FormatJson(json, &scalar_); ASSERT_TRUE(formatted.ok()) << formatted.error(); EXPECT_FALSE(IsJsonEq(json, *formatted)) << message; - EXPECT_FALSE(EqReformattedJson(json, &error_)) - << "EqReformattedJson should return false"; + EXPECT_FALSE(EqReformattedJson(json, &error_)) << "EqReformattedJson should return false"; } static const std::vector<ScalarTestErrorParam> gScalarTestErrorParams = { @@ -287,8 +274,7 @@ static const std::vector<ScalarTestErrorParam> gScalarTestErrorParams = { {"{\"e\": 1}", "Should not allow integers for enums"}, }; -INSTANTIATE_TEST_SUITE_P(Jsonpb, ScalarTestError, - ::testing::ValuesIn(gScalarTestErrorParams)); +INSTANTIATE_TEST_SUITE_P(Jsonpb, ScalarTestError, ::testing::ValuesIn(gScalarTestErrorParams)); int main(int argc, char** argv) { using ::testing::AddGlobalTestEnvironment; diff --git a/libjsonpb/verify/verify.cpp b/libjsonpb/verify/verify.cpp index c411de81..c879afb6 100644 --- a/libjsonpb/verify/verify.cpp +++ b/libjsonpb/verify/verify.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ - #include <jsonpb/verify.h> #include <iostream> @@ -47,13 +46,11 @@ const std::string& GetJsonName(const FieldDescriptor& field_descriptor) { // bumped. FieldDescriptorProto proto; field_descriptor.CopyTo(&proto); - return proto.has_json_name() ? field_descriptor.json_name() - : field_descriptor.name(); + return proto.has_json_name() ? field_descriptor.json_name() : field_descriptor.name(); } bool AllFieldsAreKnown(const Message& message, const Json::Value& json, - std::vector<std::string>* path, - std::stringstream* error) { + std::vector<std::string>* path, std::stringstream* error) { if (!json.isObject()) { *error << base::Join(*path, ".") << ": Not a JSON object\n"; return false; @@ -69,14 +66,12 @@ bool AllFieldsAreKnown(const Message& message, const Json::Value& json, } std::set<std::string> unknown_keys; - std::set_difference(json_keys.begin(), json_keys.end(), known_keys.begin(), - known_keys.end(), + std::set_difference(json_keys.begin(), json_keys.end(), known_keys.begin(), known_keys.end(), std::inserter(unknown_keys, unknown_keys.begin())); if (!unknown_keys.empty()) { *error << base::Join(*path, ".") << ": contains unknown keys: [" - << base::Join(unknown_keys, ", ") - << "]. Keys must be a known field name of " + << base::Join(unknown_keys, ", ") << "]. Keys must be a known field name of " << descriptor->full_name() << "(or its json_name option if set): [" << base::Join(known_keys, ", ") << "]\n"; return false; @@ -89,8 +84,7 @@ bool AllFieldsAreKnown(const Message& message, const Json::Value& json, std::vector<const FieldDescriptor*> set_field_descriptors; reflection->ListFields(message, &set_field_descriptors); for (auto&& field_descriptor : set_field_descriptors) { - if (field_descriptor->cpp_type() != - FieldDescriptor::CppType::CPPTYPE_MESSAGE) { + if (field_descriptor->cpp_type() != FieldDescriptor::CppType::CPPTYPE_MESSAGE) { continue; } if (field_descriptor->is_map()) { @@ -101,20 +95,17 @@ bool AllFieldsAreKnown(const Message& message, const Json::Value& json, const Json::Value& json_value = json[json_name]; if (field_descriptor->is_repeated()) { - auto&& fields = - reflection->GetRepeatedFieldRef<Message>(message, field_descriptor); + auto&& fields = reflection->GetRepeatedFieldRef<Message>(message, field_descriptor); if (json_value.type() != Json::ValueType::arrayValue) { - *error << base::Join(*path, ".") - << ": not a JSON list. This should not happen.\n"; + *error << base::Join(*path, ".") << ": not a JSON list. This should not happen.\n"; success = false; continue; } if (json_value.size() != static_cast<size_t>(fields.size())) { - *error << base::Join(*path, ".") << ": JSON list has size " - << json_value.size() << " but message has size " << fields.size() - << ". This should not happen.\n"; + *error << base::Join(*path, ".") << ": JSON list has size " << json_value.size() + << " but message has size " << fields.size() << ". This should not happen.\n"; success = false; continue; } @@ -122,8 +113,8 @@ bool AllFieldsAreKnown(const Message& message, const Json::Value& json, std::unique_ptr<Message> scratch_space(fields.NewMessage()); for (int i = 0; i < fields.size(); ++i) { path->push_back(json_name + "[" + std::to_string(i) + "]"); - auto res = AllFieldsAreKnown(fields.Get(i, scratch_space.get()), - json_value[i], path, error); + auto res = + AllFieldsAreKnown(fields.Get(i, scratch_space.get()), json_value[i], path, error); path->pop_back(); if (!res) { success = false; @@ -142,8 +133,8 @@ bool AllFieldsAreKnown(const Message& message, const Json::Value& json, return success; } -bool AllFieldsAreKnown(const google::protobuf::Message& message, - const std::string& json, std::string* error) { +bool AllFieldsAreKnown(const google::protobuf::Message& message, const std::string& json, + std::string* error) { Json::Reader reader; Json::Value value; if (!reader.parse(json, value)) { @@ -160,8 +151,7 @@ bool AllFieldsAreKnown(const google::protobuf::Message& message, return true; } -bool EqReformattedJson(const std::string& json, - google::protobuf::Message* scratch_space, +bool EqReformattedJson(const std::string& json, google::protobuf::Message* scratch_space, std::string* error) { Json::Reader reader; Json::Value old_json; @@ -207,8 +197,7 @@ bool EqReformattedJson(const std::string& json, } namespace internal { -ErrorOr<std::string> FormatJson(const std::string& json, - google::protobuf::Message* scratch_space) { +ErrorOr<std::string> FormatJson(const std::string& json, google::protobuf::Message* scratch_space) { auto res = internal::JsonStringToMessage(json, scratch_space); if (!res.ok()) { return MakeError<std::string>(res.error()); |