This is an automated email from the ASF dual-hosted git repository. szaszm pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
commit 2e9e78cd72cea8c97460bc7db2cb584e5deb3c8f Author: Adam Debreceni <adebrec...@apache.org> AuthorDate: Fri May 10 15:50:47 2024 +0200 MINIFICPP-2347 Add path of the json node to the exception Closes #1778 Signed-off-by: Marton Szasz <sza...@apache.org> --- libminifi/include/core/flow/Node.h | 15 ++++++++------- libminifi/include/core/json/JsonNode.h | 34 +++++++++++++++++----------------- libminifi/src/core/flow/Node.cpp | 5 +++-- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/libminifi/include/core/flow/Node.h b/libminifi/include/core/flow/Node.h index f871e1216..eed8ce9b6 100644 --- a/libminifi/include/core/flow/Node.h +++ b/libminifi/include/core/flow/Node.h @@ -52,6 +52,7 @@ class Node { virtual std::unique_ptr<IteratorImpl> clone() const = 0; virtual ~IteratorImpl() = default; + std::string path_; }; Iterator& operator++() { @@ -79,7 +80,6 @@ class Node { private: std::unique_ptr<IteratorImpl> impl_; - std::string path_; int idx_{0}; }; @@ -108,6 +108,8 @@ class Node { virtual Node createEmpty() const = 0; virtual ~NodeImpl() = default; + + std::string path_; }; Node() = default; @@ -124,7 +126,7 @@ class Node { nonstd::expected<std::string, std::exception_ptr> getIntegerAsString() const {return impl_->getIntegerAsString();} nonstd::expected<std::string, std::exception_ptr> getScalarAsString() const {return impl_->getScalarAsString();} - // return a string representation of the node (need not to be deserializable) + // return a string representation of the node (need not be deserializable) std::string getDebugString() const {return impl_->getDebugString();} size_t size() const {return impl_->size();} @@ -133,19 +135,19 @@ class Node { } Iterator begin() const { Iterator it = impl_->begin(); - it.path_ = path_; + it.impl_->path_ = impl_->path_; return it; } Iterator end() const { Iterator it = impl_->end(); - it.path_ = path_; + it.impl_->path_ = impl_->path_; return it; } // considers @key to be a member of this node as is Node getMember(std::string_view key) { Node result = impl_->operator[](key); - result.path_ = utils::string::join_pack(path_, "/", key); + result.impl_->path_ = utils::string::join_pack(impl_->path_, "/", key); return result; } @@ -175,13 +177,12 @@ class Node { return impl_->createEmpty(); } - std::string getPath() const {return path_;} + std::string getPath() const {return impl_->path_;} std::optional<Cursor> getCursor() const {return impl_->getCursor();} private: std::shared_ptr<NodeImpl> impl_; - std::string path_; }; class Node::Iterator::Value : public Node, public std::pair<Node, Node> { diff --git a/libminifi/include/core/json/JsonNode.h b/libminifi/include/core/json/JsonNode.h index bb11ca251..f6b9b1c9f 100644 --- a/libminifi/include/core/json/JsonNode.h +++ b/libminifi/include/core/json/JsonNode.h @@ -53,10 +53,10 @@ class JsonNode : public flow::Node::NodeImpl { nonstd::expected<std::string, std::exception_ptr> getString() const override { try { if (!node_) { - throw std::runtime_error("Cannot get string of invalid json value"); + throw std::runtime_error(fmt::format("Cannot get string of invalid json value at '{}'", path_)); } if (!node_->IsString()) { - throw std::runtime_error("Cannot get string of non-string json value"); + throw std::runtime_error(fmt::format("Cannot get string of non-string json value at '{}'", path_)); } return std::string{node_->GetString(), node_->GetStringLength()}; } catch (...) { @@ -67,10 +67,10 @@ class JsonNode : public flow::Node::NodeImpl { nonstd::expected<int64_t, std::exception_ptr> getInt64() const override { try { if (!node_) { - throw std::runtime_error("Cannot get int64 of invalid json value"); + throw std::runtime_error(fmt::format("Cannot get int64 of invalid json value at '{}'", path_)); } if (!node_->IsInt64()) { - throw std::runtime_error("Cannot get int64 of non-int64 json value"); + throw std::runtime_error(fmt::format("Cannot get int64 of non-int64 json value at '{}'", path_)); } return node_->GetInt64(); } catch (...) { @@ -81,10 +81,10 @@ class JsonNode : public flow::Node::NodeImpl { nonstd::expected<bool, std::exception_ptr> getBool() const override { try { if (!node_) { - throw std::runtime_error("Cannot get bool of invalid json value"); + throw std::runtime_error(fmt::format("Cannot get bool of invalid json value at '{}'", path_)); } if (!node_->IsBool()) { - throw std::runtime_error("Cannot get bool of non-bool json value"); + throw std::runtime_error(fmt::format("Cannot get bool of non-bool json value at '{}'", path_)); } return node_->GetBool(); } catch (...) { @@ -94,11 +94,11 @@ class JsonNode : public flow::Node::NodeImpl { nonstd::expected<std::string, std::exception_ptr> getIntegerAsString() const override { try { - if (!node_) throw std::runtime_error("Cannot get string from invalid json value"); + if (!node_) throw std::runtime_error(fmt::format("Cannot get string from invalid json value at '{}'", path_)); if (node_->IsInt64()) return std::to_string(node_->GetInt64()); if (node_->IsUint64()) return std::to_string(node_->GetUint64()); if (node_->IsString()) return std::string(node_->GetString(), node_->GetStringLength()); - throw std::runtime_error("Cannot get string from non-integer json value"); + throw std::runtime_error(fmt::format("Cannot get string from non-integer json value at '{}'", path_)); } catch (...) { return nonstd::make_unexpected(std::current_exception()); } @@ -106,13 +106,13 @@ class JsonNode : public flow::Node::NodeImpl { nonstd::expected<std::string, std::exception_ptr> getScalarAsString() const override { try { - if (!node_) throw std::runtime_error("Cannot get string from invalid json value"); + if (!node_) throw std::runtime_error(fmt::format("Cannot get string from invalid json value at '{}'", path_)); if (node_->IsBool()) return node_->GetBool() ? "true" : "false"; if (node_->IsInt64()) return std::to_string(node_->GetInt64()); if (node_->IsUint64()) return std::to_string(node_->GetUint64()); if (node_->IsString()) return std::string(node_->GetString(), node_->GetStringLength()); if (node_->IsDouble()) return std::to_string(node_->GetDouble()); - throw std::runtime_error("Cannot convert non-scalar json value to string"); + throw std::runtime_error(fmt::format("Cannot convert non-scalar json value to string at '{}'", path_)); } catch (...) { return nonstd::make_unexpected(std::current_exception()); } @@ -135,10 +135,10 @@ class JsonNode : public flow::Node::NodeImpl { size_t size() const override { if (!node_) { - throw std::runtime_error("Cannot get size of invalid json value"); + throw std::runtime_error(fmt::format("Cannot get size of invalid json value at '{}'", path_)); } if (!node_->IsArray()) { - throw std::runtime_error("Cannot get size of non-array json value"); + throw std::runtime_error(fmt::format("Cannot get size of non-array json value at '{}'", path_)); } return node_->Size(); } @@ -150,7 +150,7 @@ class JsonNode : public flow::Node::NodeImpl { return flow::Node{std::make_shared<JsonNode>(nullptr)}; } if (!node_->IsObject()) { - throw std::runtime_error("Cannot get member of scalar json value"); + throw std::runtime_error(fmt::format("Cannot get member '{}' of scalar json value at '{}'", key, path_)); } auto it = node_->FindMember(rapidjson::Value(rapidjson::StringRef(key.data(), key.length()))); if (it == node_->MemberEnd()) { @@ -225,27 +225,27 @@ class JsonMemberIterator : public flow::Node::Iterator::IteratorImpl { inline flow::Node::Iterator JsonNode::begin() const { if (!node_) { - throw std::runtime_error("Cannot get begin of invalid json value"); + throw std::runtime_error(fmt::format("Cannot get begin of invalid json value at '{}'", path_)); } if (node_->IsArray()) { return flow::Node::Iterator{std::make_unique<JsonValueIterator>(node_->Begin())}; } else if (node_->IsObject()) { return flow::Node::Iterator{std::make_unique<JsonMemberIterator>(node_->MemberBegin())}; } else { - throw std::runtime_error("Json node is not iterable, neither array nor object"); + throw std::runtime_error(fmt::format("Json node is not iterable, neither array nor object at '{}'", path_)); } } inline flow::Node::Iterator JsonNode::end() const { if (!node_) { - throw std::runtime_error("Cannot get end of invalid json value"); + throw std::runtime_error(fmt::format("Cannot get end of invalid json value at '{}'", path_)); } if (node_->IsArray()) { return flow::Node::Iterator{std::make_unique<JsonValueIterator>(node_->End())}; } else if (node_->IsObject()) { return flow::Node::Iterator{std::make_unique<JsonMemberIterator>(node_->MemberEnd())}; } else { - throw std::runtime_error("Json node is not iterable, neither array nor object"); + throw std::runtime_error(fmt::format("Json node is not iterable, neither array nor object at '{}'", path_)); } } diff --git a/libminifi/src/core/flow/Node.cpp b/libminifi/src/core/flow/Node.cpp index 129303905..48c322dfd 100644 --- a/libminifi/src/core/flow/Node.cpp +++ b/libminifi/src/core/flow/Node.cpp @@ -17,6 +17,7 @@ */ #include "core/flow/Node.h" +#include "fmt/format.h" namespace org::apache::nifi::minifi::core::flow { @@ -24,10 +25,10 @@ Node::Iterator::Value Node::Iterator::operator*() const { Value value = impl_->operator*(); if (value) { // sequence iterator - value.path_ = utils::string::join_pack(path_, "/", std::to_string(idx_)); + value.impl_->path_ = utils::string::join_pack(impl_->path_, "/", std::to_string(idx_)); } else if (value.second) { // map iterator - value.second.path_ = utils::string::join_pack(path_, "/", value.first.getString().value()); + value.second.impl_->path_ = utils::string::join_pack(impl_->path_, "/", value.first.getString().value()); } return value; }