add error handling/reporting for client module

Change-Id: I38875e561aa85093030ad6f937891723bd401de2
diff --git a/src/client-module.cpp b/src/client-module.cpp
index 8fdb7b2..46405bb 100644
--- a/src/client-module.cpp
+++ b/src/client-module.cpp
@@ -35,6 +35,8 @@
 #include "protocol-detail/new.hpp"
 #include "protocol-detail/probe.hpp"
 #include "protocol-detail/revoke.hpp"
+#include "protocol-detail/error.hpp"
+#include "ndncert-common.hpp"
 
 namespace ndn {
 namespace ndncert {
@@ -123,6 +125,9 @@
     return;
   }
 
+  // error handling
+  processIfError(reply);
+
   auto contentTLV = reply.getContent();
   contentTLV.parse();
 
@@ -217,6 +222,10 @@
     _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
     return std::list<std::string>();
   }
+
+  // error handling
+  processIfError(reply);
+
   auto contentTLV = reply.getContent();
   contentTLV.parse();
 
@@ -300,6 +309,10 @@
     _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
     return;
   }
+
+  // error handling
+  processIfError(reply);
+
   auto result = decodeBlockWithAesGcm128(reply.getContent(), m_aesKey, (const uint8_t*)"test", strlen("test"));
 
   Block contentTLV = makeBinaryBlock(tlv_encrypted_payload, result.data(), result.size());
@@ -373,5 +386,22 @@
   m_status = Status::ENDED;
 }
 
+void
+ClientModule::processIfError(const Data& data)
+{
+  auto contentTLV = data.getContent();
+  if (ErrorTLV::isErrorContent(contentTLV)) {
+  try {
+    auto error = ErrorTLV::decodefromDataContent(contentTLV);
+    _LOG_ERROR("Error data returned for " << data.getName() << ": " << std::endl <<
+               "Code: " << errorCodeToString(std::get<0>(error)) << std::endl <<
+               "Info: " << std::get<1>(error) << std::endl);
+    } catch (const std::exception& e) {
+      _LOG_ERROR("Cannot parse error data content for " << data.getName());
+      return;
+    }
+  }
+}
+
 }  // namespace ndncert
 }  // namespace ndn
diff --git a/src/client-module.hpp b/src/client-module.hpp
index fd88129..b9c0f35 100644
--- a/src/client-module.hpp
+++ b/src/client-module.hpp
@@ -117,6 +117,9 @@
   void
   endSession();
 
+  static void
+  processIfError(const Data& data);
+
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   ClientConfig m_config;
   security::v2::KeyChain& m_keyChain;
diff --git a/src/ndncert-common.cpp b/src/ndncert-common.cpp
index 086d880..3e31596 100644
--- a/src/ndncert-common.cpp
+++ b/src/ndncert-common.cpp
@@ -62,6 +62,24 @@
   }
 }
 
+std::map<ErrorCode, std::string> errorCodeText = {
+  {ErrorCode::NO_ERROR,             "NO_ERROR"},
+  {ErrorCode::BAD_INTEREST_FORMAT,  "BAD_INTEREST_FORMAT"},
+  {ErrorCode::BAD_PARAMETER_FORMAT, "BAD_PARAMETER_FORMAT"},
+  {ErrorCode::BAD_SIGNATURE,        "BAD_SIGNATURE"},
+  {ErrorCode::INVALID_PARAMETER,    "INVALID_PARAMETER"},
+  {ErrorCode::NAME_NOT_ALLOWED,     "NAME_NOT_ALLOWED"},
+  {ErrorCode::BAD_VALIDITY_PERIOD,  "BAD_VALIDITY_PERIOD"},
+  {ErrorCode::OUT_OF_TRIES,         "OUT_OF_TRIES"},
+  {ErrorCode::OUT_OF_TIME,          "OUT_OF_TIME"},
+  {ErrorCode::NO_AVAILABLE_NAMES,   "NO_AVAILABLE_NAMES"}
+};
+
+std::string errorCodeToString(ErrorCode code)
+{
+  return errorCodeText.at(code);
+}
+
 std::string
 convertJson2String(const JsonSection& json)
 {
diff --git a/src/ndncert-common.hpp b/src/ndncert-common.hpp
index d052d62..a9165a2 100644
--- a/src/ndncert-common.hpp
+++ b/src/ndncert-common.hpp
@@ -155,6 +155,8 @@
 
 std::string requestTypeToString(RequestType type);
 
+std::string errorCodeToString(ErrorCode code);
+
 typedef boost::property_tree::ptree JsonSection;
 
 std::string
diff --git a/src/protocol-detail/error.cpp b/src/protocol-detail/error.cpp
index 739c3b7..b74180b 100644
--- a/src/protocol-detail/error.cpp
+++ b/src/protocol-detail/error.cpp
@@ -42,5 +42,12 @@
   return std::make_tuple(error, description);
 }
 
+bool
+ErrorTLV::isErrorContent(const Block& block)
+{
+  block.parse();
+  return block.find(tlv_error_code) != block.elements_end();
+}
+
 }  // namespace ndncert
 }  // namespace ndn
diff --git a/src/protocol-detail/error.hpp b/src/protocol-detail/error.hpp
index 8a2cda0..d39fe1a 100644
--- a/src/protocol-detail/error.hpp
+++ b/src/protocol-detail/error.hpp
@@ -39,6 +39,9 @@
    */
   static std::tuple<ErrorCode, std::string>
   decodefromDataContent(const Block& block);
+
+  static bool
+  isErrorContent(const Block& block);
 };
 
 }  // namespace ndncert