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;
 }

Reply via email to