rib+tools: adapt to Controller::CommandFailCallback with ControlResponse

refs #3739

Change-Id: Icf5b3ed0bd997730a024bad2ccd258c8168b4ccb
diff --git a/rib/auto-prefix-propagator.cpp b/rib/auto-prefix-propagator.cpp
index 1d87208..c597e82 100644
--- a/rib/auto-prefix-propagator.cpp
+++ b/rib/auto-prefix-propagator.cpp
@@ -282,7 +282,7 @@
      parameters,
      bind(&AutoPrefixPropagator::afterPropagateSucceed, this, parameters, options, refreshEvent),
      bind(&AutoPrefixPropagator::afterPropagateFail,
-          this, _1, _2, parameters, options, retryWaitTime, retryEvent),
+          this, _1, parameters, options, retryWaitTime, retryEvent),
      options);
 }
 
@@ -296,7 +296,7 @@
   m_nfdController.start<ndn::nfd::RibUnregisterCommand>(
      parameters,
      bind(&AutoPrefixPropagator::afterRevokeSucceed, this, parameters, options, retryWaitTime),
-     bind(&AutoPrefixPropagator::afterRevokeFail, this, _1, _2, parameters, options),
+     bind(&AutoPrefixPropagator::afterRevokeFail, this, _1, parameters, options),
      options);
 }
 
@@ -399,14 +399,14 @@
 }
 
 void
-AutoPrefixPropagator::afterPropagateFail(uint32_t code, const std::string& reason,
+AutoPrefixPropagator::afterPropagateFail(const ndn::nfd::ControlResponse& response,
                                          const ControlParameters& parameters,
                                          const CommandOptions& options,
                                          time::seconds retryWaitTime,
                                          const ndn::Scheduler::Event& retryEvent)
 {
   NFD_LOG_TRACE("fail to propagate " << parameters.getName()
-                                     << "\n\t reason:" << reason
+                                     << "\n\t reason:" << response.getText()
                                      << "\n\t retry wait time: " << retryWaitTime);
 
   auto entryIt = m_propagatedEntries.find(parameters.getName());
@@ -442,12 +442,12 @@
 }
 
 void
-AutoPrefixPropagator::afterRevokeFail(uint32_t code, const std::string& reason,
-                                       const ControlParameters& parameters,
-                                       const CommandOptions& options)
+AutoPrefixPropagator::afterRevokeFail(const ndn::nfd::ControlResponse& response,
+                                      const ControlParameters& parameters,
+                                      const CommandOptions& options)
 {
   NFD_LOG_INFO("fail to revoke the propagation of  " << parameters.getName()
-                                                     << "\n\t reason:" << reason);
+                                                     << "\n\t reason:" << response.getText());
 }
 
 void
diff --git a/rib/auto-prefix-propagator.hpp b/rib/auto-prefix-propagator.hpp
index 11ad67f..483ab68 100644
--- a/rib/auto-prefix-propagator.hpp
+++ b/rib/auto-prefix-propagator.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -321,15 +321,14 @@
    * If the PropagatedEntry still exists, schedule a retry timer to redo propagation
    * after a duration defined by current retry time @p retryWaitTime
    *
-   * @param code error code.
-   * @param reason error reason in string.
+   * @param response ControlResponse from remote NFD-RIB
    * @param parameters the ControlParameters used by the registration command for propagation
    * @param options the CommandOptions used by registration command for propagation
    * @param retryWaitTime the current wait time before retrying propagation
    * @param retryEvent the event of retrying propagation
    */
   void
-  afterPropagateFail(uint32_t code, const std::string& reason,
+  afterPropagateFail(const ndn::nfd::ControlResponse& response,
                      const ndn::nfd::ControlParameters& parameters,
                      const ndn::nfd::CommandOptions& options,
                      time::seconds retryWaitTime,
@@ -357,13 +356,12 @@
   /**
    * @brief invoked after revocation fails.
    *
-   * @param code error code.
-   * @param reason error reason in string.
+   * @param response ControlResponse from remote NFD-RIB
    * @param parameters the ControlParameters used by the unregistration command for revocation
    * @param options the CommandOptions used by the unregistration command for revocation
    */
   void
-  afterRevokeFail(uint32_t code, const std::string& reason,
+  afterRevokeFail(const ndn::nfd::ControlResponse& response,
                   const ndn::nfd::ControlParameters& parameters,
                   const ndn::nfd::CommandOptions& options);
 
diff --git a/rib/fib-updater.cpp b/rib/fib-updater.cpp
index c467072..c6b4f09 100644
--- a/rib/fib-updater.cpp
+++ b/rib/fib-updater.cpp
@@ -243,7 +243,7 @@
       .setFaceId(update.faceId)
       .setCost(update.cost),
     bind(&FibUpdater::onUpdateSuccess, this, update, onSuccess, onFailure),
-    bind(&FibUpdater::onUpdateError, this, update, onSuccess, onFailure, _1, _2, nTimeouts));
+    bind(&FibUpdater::onUpdateError, this, update, onSuccess, onFailure, _1, nTimeouts));
 }
 
 void
@@ -257,7 +257,7 @@
       .setName(update.name)
       .setFaceId(update.faceId),
     bind(&FibUpdater::onUpdateSuccess, this, update, onSuccess, onFailure),
-    bind(&FibUpdater::onUpdateError, this, update, onSuccess, onFailure, _1, _2, nTimeouts));
+    bind(&FibUpdater::onUpdateError, this, update, onSuccess, onFailure, _1, nTimeouts));
 }
 
 void
@@ -285,16 +285,18 @@
 FibUpdater::onUpdateError(const FibUpdate update,
                           const FibUpdateSuccessCallback& onSuccess,
                           const FibUpdateFailureCallback& onFailure,
-                          uint32_t code, const std::string& error, uint32_t nTimeouts)
+                          const ndn::nfd::ControlResponse& response, uint32_t nTimeouts)
 {
-  NFD_LOG_DEBUG("Failed to apply " << update << " (code: " << code << ", error: " << error << ")");
+  uint32_t code = response.getCode();
+  NFD_LOG_DEBUG("Failed to apply " << update <<
+                " (code: " << code << ", error: " << response.getText() << ")");
 
   if (code == ndn::nfd::Controller::ERROR_TIMEOUT && nTimeouts < MAX_NUM_TIMEOUTS) {
     sendAddNextHopUpdate(update, onSuccess, onFailure, ++nTimeouts);
   }
   else if (code == ERROR_FACE_NOT_FOUND) {
     if (update.faceId == m_batchFaceId) {
-      onFailure(code, error);
+      onFailure(code, response.getText());
     }
     else {
       m_updatesForNonBatchFaceId.remove(update);
@@ -305,7 +307,8 @@
     }
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("Non-recoverable error: " + error + " code: " + to_string(code)));
+    BOOST_THROW_EXCEPTION(Error("Non-recoverable error: " + response.getText() +
+                                " code: " + to_string(code)));
   }
 }
 
diff --git a/rib/fib-updater.hpp b/rib/fib-updater.hpp
index 2d7761a..fed7aed 100644
--- a/rib/fib-updater.hpp
+++ b/rib/fib-updater.hpp
@@ -173,7 +173,7 @@
   onUpdateError(const FibUpdate update,
                 const FibUpdateSuccessCallback& onSuccess,
                 const FibUpdateFailureCallback& onFailure,
-                uint32_t code, const std::string& error, uint32_t nTimeouts);
+                const ndn::nfd::ControlResponse& response, uint32_t nTimeouts);
 
 private:
   /** \brief adds the update to an update list based on its Face ID
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
index e581095..dd0abca 100644
--- a/rib/rib-manager.cpp
+++ b/rib/rib-manager.cpp
@@ -94,7 +94,7 @@
     ControlParameters()
       .setLocalControlFeature(ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID),
     bind(&RibManager::onControlHeaderSuccess, this),
-    bind(&RibManager::onControlHeaderError, this, _1, _2));
+    bind(&RibManager::onControlHeaderError, this, _1));
 }
 
 void
@@ -165,7 +165,7 @@
        .setName(Name(topPrefix).append(MGMT_MODULE_NAME))
        .setFaceId(0),
      bind(&RibManager::onCommandPrefixAddNextHopSuccess, this, cref(topPrefix), _1),
-     bind(&RibManager::onCommandPrefixAddNextHopError, this, cref(topPrefix), _2));
+     bind(&RibManager::onCommandPrefixAddNextHopError, this, cref(topPrefix), _1));
 
   // add top prefix to the dispatcher
   m_addTopPrefix(topPrefix);
@@ -443,9 +443,11 @@
 }
 
 void
-RibManager::onCommandPrefixAddNextHopError(const Name& name, const std::string& msg)
+RibManager::onCommandPrefixAddNextHopError(const Name& name,
+                                           const ndn::nfd::ControlResponse& response)
 {
-  BOOST_THROW_EXCEPTION(Error("Error in setting interest filter (" + name.toUri() + "): " + msg));
+  BOOST_THROW_EXCEPTION(Error("Error in setting interest filter (" + name.toUri() +
+                              "): " + response.getText()));
 }
 
 void
@@ -455,11 +457,11 @@
 }
 
 void
-RibManager::onControlHeaderError(uint32_t code, const std::string& reason)
+RibManager::onControlHeaderError(const ndn::nfd::ControlResponse& response)
 {
   std::ostringstream os;
   os << "Couldn't enable local control header "
-     << "(code: " << code << ", info: " << reason << ")";
+     << "(code: " << response.getCode() << ", info: " << response.getText() << ")";
   BOOST_THROW_EXCEPTION(Error(os.str()));
 }
 
diff --git a/rib/rib-manager.hpp b/rib/rib-manager.hpp
index 55ee394..998a284 100644
--- a/rib/rib-manager.hpp
+++ b/rib/rib-manager.hpp
@@ -169,13 +169,13 @@
                                    const ndn::nfd::ControlParameters& result);
 
   void
-  onCommandPrefixAddNextHopError(const Name& name, const std::string& msg);
+  onCommandPrefixAddNextHopError(const Name& name, const ndn::nfd::ControlResponse& response);
 
   void
   onControlHeaderSuccess();
 
   void
-  onControlHeaderError(uint32_t code, const std::string& reason);
+  onControlHeaderError(const ndn::nfd::ControlResponse& response);
 
 private:
   ndn::Face& m_face;
diff --git a/tests/rib/auto-prefix-propagator.t.cpp b/tests/rib/auto-prefix-propagator.t.cpp
index 7db7510..ebdf94b 100644
--- a/tests/rib/auto-prefix-propagator.t.cpp
+++ b/tests/rib/auto-prefix-propagator.t.cpp
@@ -631,8 +631,9 @@
     wasRetryEventTriggered = false;
 
     auto propagateParameters = m_propagator.getPrefixPropagationParameters(ribEntryPrefix);
-    m_propagator.afterPropagateFail(400, "test", propagateParameters.parameters, propagateParameters.options,
-                                     time::seconds(0), [&]{ wasRetryEventTriggered = true; });
+    m_propagator.afterPropagateFail(ndn::nfd::ControlResponse(400, "test"),
+                                    propagateParameters.parameters, propagateParameters.options,
+                                    time::seconds(0), [&] { wasRetryEventTriggered = true; });
     advanceClocks(time::milliseconds(1));
   };
 
diff --git a/tests/tools/nfdc/status-report.t.cpp b/tests/tools/nfdc/status-report.t.cpp
index 2d89868..55e452c 100644
--- a/tests/tools/nfdc/status-report.t.cpp
+++ b/tests/tools/nfdc/status-report.t.cpp
@@ -72,7 +72,7 @@
   virtual void
   fetchStatus(Controller& controller,
               const function<void()>& onSuccess,
-              const Controller::CommandFailCallback& onFailure,
+              const Controller::DatasetFailCallback& onFailure,
               const CommandOptions& options) override
   {
     ++nFetchStatusCalls;
diff --git a/tools/ndn-autoconfig/base.cpp b/tools/ndn-autoconfig/base.cpp
index c896e67..a796f4c 100644
--- a/tools/ndn-autoconfig/base.cpp
+++ b/tools/ndn-autoconfig/base.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -57,7 +57,7 @@
   m_controller.start<nfd::FaceCreateCommand>(nfd::ControlParameters()
                                                .setUri(canonicalUri.toString()),
                                              bind(&Base::onHubConnectSuccess, this, _1),
-                                             bind(&Base::onHubConnectError, this, _1, _2));
+                                             bind(&Base::onHubConnectError, this, _1));
 }
 
 void
@@ -81,10 +81,10 @@
 }
 
 void
-Base::onHubConnectError(uint32_t code, const std::string& error)
+Base::onHubConnectError(const nfd::ControlResponse& response)
 {
   std::ostringstream os;
-  os << "Failed to create face: " << error << " (code: " << code << ")";
+  os << "Failed to create face: " << response.getText() << " (code: " << response.getCode() << ")";
   BOOST_THROW_EXCEPTION(Error(os.str()));
 }
 
@@ -99,7 +99,7 @@
                                                 .setCost(100)
                                                 .setExpirationPeriod(time::milliseconds::max()),
                                               bind(&Base::onPrefixRegistrationSuccess, this, _1),
-                                              bind(&Base::onPrefixRegistrationError, this, _1, _2));
+                                              bind(&Base::onPrefixRegistrationError, this, _1));
 }
 
 void
@@ -109,10 +109,10 @@
 }
 
 void
-Base::onPrefixRegistrationError(uint32_t code, const std::string& error)
+Base::onPrefixRegistrationError(const nfd::ControlResponse& response)
 {
   std::ostringstream os;
-  os << "Failed in name registration, " << error << " (code: " << code << ")";
+  os << "Failed in name registration, " << response.getText() << " (code: " << response.getCode() << ")";
   BOOST_THROW_EXCEPTION(Error(os.str()));
 }
 
diff --git a/tools/ndn-autoconfig/base.hpp b/tools/ndn-autoconfig/base.hpp
index d69f49c..c4c3a9b 100644
--- a/tools/ndn-autoconfig/base.hpp
+++ b/tools/ndn-autoconfig/base.hpp
@@ -93,7 +93,7 @@
   onHubConnectSuccess(const nfd::ControlParameters& resp);
 
   void
-  onHubConnectError(uint32_t code, const std::string& error);
+  onHubConnectError(const nfd::ControlResponse& response);
 
   void
   registerPrefix(const Name& prefix, uint64_t faceId);
@@ -102,7 +102,7 @@
   onPrefixRegistrationSuccess(const nfd::ControlParameters& commandSuccessResult);
 
   void
-  onPrefixRegistrationError(uint32_t code, const std::string& error);
+  onPrefixRegistrationError(const nfd::ControlResponse& response);
 
 protected:
   Face& m_face;
diff --git a/tools/ndn-autoconfig/multicast-discovery.cpp b/tools/ndn-autoconfig/multicast-discovery.cpp
index 2e3f8a2..a474899 100644
--- a/tools/ndn-autoconfig/multicast-discovery.cpp
+++ b/tools/ndn-autoconfig/multicast-discovery.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -108,7 +108,7 @@
                                                   bind(&MulticastDiscovery::onRegisterSuccess,
                                                        this),
                                                   bind(&MulticastDiscovery::onRegisterFailure,
-                                                       this, _1, _2));
+                                                       this, _1));
     }
   }
 }
@@ -124,9 +124,9 @@
 }
 
 void
-MulticastDiscovery::onRegisterFailure(uint32_t code, const std::string& error)
+MulticastDiscovery::onRegisterFailure(const nfd::ControlResponse& response)
 {
-  std::cerr << "ERROR: " << error << " (code: " << code << ")" << std::endl;
+  std::cerr << "ERROR: " << response.getText() << " (code: " << response.getCode() << ")" << std::endl;
   --nRequestedRegs;
 
   if (nRequestedRegs == nFinishedRegs) {
@@ -150,14 +150,14 @@
   m_controller.start<nfd::StrategyChoiceSetCommand>(parameters,
                                                     bind(&MulticastDiscovery::requestHubData, this),
                                                     bind(&MulticastDiscovery::onSetStrategyFailure,
-                                                         this, _2));
+                                                         this, _1));
 }
 
 void
-MulticastDiscovery::onSetStrategyFailure(const std::string& error)
+MulticastDiscovery::onSetStrategyFailure(const nfd::ControlResponse& response)
 {
   m_nextStageOnFailure("Failed to set multicast strategy for " +
-                       LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() + " namespace (" + error + "). "
+                       LOCALHOP_HUB_DISCOVERY_PREFIX.toUri() + " namespace (" + response.getText() + "). "
                        "Skipping multicast discovery stage");
 }
 
diff --git a/tools/ndn-autoconfig/multicast-discovery.hpp b/tools/ndn-autoconfig/multicast-discovery.hpp
index 8047926..32f7133 100644
--- a/tools/ndn-autoconfig/multicast-discovery.hpp
+++ b/tools/ndn-autoconfig/multicast-discovery.hpp
@@ -69,13 +69,13 @@
   onRegisterSuccess();
 
   void
-  onRegisterFailure(uint32_t code, const std::string& error);
+  onRegisterFailure(const nfd::ControlResponse& response);
 
   void
   setStrategy();
 
   void
-  onSetStrategyFailure(const std::string& error);
+  onSetStrategyFailure(const nfd::ControlResponse& response);
 
   // Start to look for a hub (NDN hub discovery first stage)
   void
diff --git a/tools/nfd-autoreg.cpp b/tools/nfd-autoreg.cpp
index b21fe6d..996c03c 100644
--- a/tools/nfd-autoreg.cpp
+++ b/tools/nfd-autoreg.cpp
@@ -70,10 +70,11 @@
 
   void
   onRegisterCommandFailure(uint64_t faceId, const Name& prefix,
-                           uint32_t code, const std::string& reason)
+                           const nfd::ControlResponse& response)
   {
     std::cerr << "FAILED: register " << prefix << " on face " << faceId
-              << " (code: " << code << ", reason: " << reason << ")" << std::endl;
+              << " (code: " << response.getCode() << ", reason: " << response.getText() << ")"
+              << std::endl;
   }
 
   /**
@@ -137,7 +138,7 @@
             .setCost(m_cost)
             .setExpirationPeriod(time::milliseconds::max()),
           bind(&AutoregServer::onRegisterCommandSuccess, this, faceId, *prefix),
-          bind(&AutoregServer::onRegisterCommandFailure, this, faceId, *prefix, _1, _2));
+          bind(&AutoregServer::onRegisterCommandFailure, this, faceId, *prefix, _1));
       }
   }
 
diff --git a/tools/nfdc/channel-module.cpp b/tools/nfdc/channel-module.cpp
index af55d7b..15cffb4 100644
--- a/tools/nfdc/channel-module.cpp
+++ b/tools/nfdc/channel-module.cpp
@@ -33,7 +33,7 @@
 void
 ChannelModule::fetchStatus(Controller& controller,
                            const function<void()>& onSuccess,
-                           const Controller::CommandFailCallback& onFailure,
+                           const Controller::DatasetFailCallback& onFailure,
                            const CommandOptions& options)
 {
   controller.fetch<ndn::nfd::ChannelDataset>(
diff --git a/tools/nfdc/channel-module.hpp b/tools/nfdc/channel-module.hpp
index e3486a1..6225a27 100644
--- a/tools/nfdc/channel-module.hpp
+++ b/tools/nfdc/channel-module.hpp
@@ -43,7 +43,7 @@
   virtual void
   fetchStatus(Controller& controller,
               const function<void()>& onSuccess,
-              const Controller::CommandFailCallback& onFailure,
+              const Controller::DatasetFailCallback& onFailure,
               const CommandOptions& options) override;
 
   virtual void
diff --git a/tools/nfdc/face-id-fetcher.cpp b/tools/nfdc/face-id-fetcher.cpp
index da09c11..08bc9ff 100644
--- a/tools/nfdc/face-id-fetcher.cpp
+++ b/tools/nfdc/face-id-fetcher.cpp
@@ -164,12 +164,11 @@
 }
 
 void
-FaceIdFetcher::onFaceCreateError(uint32_t code,
-                                 const std::string& error,
+FaceIdFetcher::onFaceCreateError(const ndn::nfd::ControlResponse& response,
                                  const std::string& message)
 {
   std::stringstream ss;
-  ss << message << " : " << error << " (code " << code << ")";
+  ss << message << " : " << response.getText() << " (code " << response.getCode() << ")";
   fail(ss.str());
 }
 
@@ -181,7 +180,7 @@
 
   m_controller.start<ndn::nfd::FaceCreateCommand>(parameters,
     [this] (const ndn::nfd::ControlParameters& result) { succeed(result.getFaceId()); },
-    bind(&FaceIdFetcher::onFaceCreateError, this, _1, _2, "Face creation failed"));
+    bind(&FaceIdFetcher::onFaceCreateError, this, _1, "Face creation failed"));
 }
 
 void
diff --git a/tools/nfdc/face-id-fetcher.hpp b/tools/nfdc/face-id-fetcher.hpp
index 50e0083..cf0eb6f 100644
--- a/tools/nfdc/face-id-fetcher.hpp
+++ b/tools/nfdc/face-id-fetcher.hpp
@@ -88,8 +88,7 @@
   startFaceCreate(const FaceUri& canonicalUri);
 
   void
-  onFaceCreateError(uint32_t code,
-                    const std::string& error,
+  onFaceCreateError(const ndn::nfd::ControlResponse& response,
                     const std::string& message);
 
   void
diff --git a/tools/nfdc/face-module.cpp b/tools/nfdc/face-module.cpp
index 9c5e74c..97e836c 100644
--- a/tools/nfdc/face-module.cpp
+++ b/tools/nfdc/face-module.cpp
@@ -53,7 +53,7 @@
 void
 FaceModule::fetchStatus(Controller& controller,
                         const function<void()>& onSuccess,
-                        const Controller::CommandFailCallback& onFailure,
+                        const Controller::DatasetFailCallback& onFailure,
                         const CommandOptions& options)
 {
   controller.fetch<ndn::nfd::FaceDataset>(
diff --git a/tools/nfdc/face-module.hpp b/tools/nfdc/face-module.hpp
index 3f8020f..27c089b 100644
--- a/tools/nfdc/face-module.hpp
+++ b/tools/nfdc/face-module.hpp
@@ -43,7 +43,7 @@
   virtual void
   fetchStatus(Controller& controller,
               const function<void()>& onSuccess,
-              const Controller::CommandFailCallback& onFailure,
+              const Controller::DatasetFailCallback& onFailure,
               const CommandOptions& options) override;
 
   virtual void
diff --git a/tools/nfdc/fib-module.cpp b/tools/nfdc/fib-module.cpp
index 27d3922..3da24ee 100644
--- a/tools/nfdc/fib-module.cpp
+++ b/tools/nfdc/fib-module.cpp
@@ -33,7 +33,7 @@
 void
 FibModule::fetchStatus(Controller& controller,
                        const function<void()>& onSuccess,
-                       const Controller::CommandFailCallback& onFailure,
+                       const Controller::DatasetFailCallback& onFailure,
                        const CommandOptions& options)
 {
   controller.fetch<ndn::nfd::FibDataset>(
diff --git a/tools/nfdc/fib-module.hpp b/tools/nfdc/fib-module.hpp
index 2472bd5..6c33d64 100644
--- a/tools/nfdc/fib-module.hpp
+++ b/tools/nfdc/fib-module.hpp
@@ -44,7 +44,7 @@
   virtual void
   fetchStatus(Controller& controller,
               const function<void()>& onSuccess,
-              const Controller::CommandFailCallback& onFailure,
+              const Controller::DatasetFailCallback& onFailure,
               const CommandOptions& options) override;
 
   virtual void
diff --git a/tools/nfdc/forwarder-general-module.cpp b/tools/nfdc/forwarder-general-module.cpp
index 481fd40..dc12e96 100644
--- a/tools/nfdc/forwarder-general-module.cpp
+++ b/tools/nfdc/forwarder-general-module.cpp
@@ -38,7 +38,7 @@
 void
 ForwarderGeneralModule::fetchStatus(Controller& controller,
                                     const function<void()>& onSuccess,
-                                    const Controller::CommandFailCallback& onFailure,
+                                    const Controller::DatasetFailCallback& onFailure,
                                     const CommandOptions& options)
 {
   controller.fetch<ndn::nfd::ForwarderGeneralStatusDataset>(
diff --git a/tools/nfdc/forwarder-general-module.hpp b/tools/nfdc/forwarder-general-module.hpp
index 9bcf929..f8c30d8 100644
--- a/tools/nfdc/forwarder-general-module.hpp
+++ b/tools/nfdc/forwarder-general-module.hpp
@@ -48,7 +48,7 @@
   virtual void
   fetchStatus(Controller& controller,
               const function<void()>& onSuccess,
-              const Controller::CommandFailCallback& onFailure,
+              const Controller::DatasetFailCallback& onFailure,
               const CommandOptions& options) override;
 
   void
diff --git a/tools/nfdc/legacy-nfdc.cpp b/tools/nfdc/legacy-nfdc.cpp
index 83a3db8..3e4c0e6 100644
--- a/tools/nfdc/legacy-nfdc.cpp
+++ b/tools/nfdc/legacy-nfdc.cpp
@@ -113,7 +113,7 @@
 
       m_controller.start<ndn::nfd::FibAddNextHopCommand>(parameters,
         bind(&LegacyNfdc::onSuccess, this, _1, "Nexthop insertion succeeded"),
-        bind(&LegacyNfdc::onError, this, _1, _2, "Nexthop insertion failed"));
+        bind(&LegacyNfdc::onError, this, _1, "Nexthop insertion failed"));
     },
     bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
 }
@@ -133,7 +133,7 @@
 
       m_controller.start<ndn::nfd::FibRemoveNextHopCommand>(parameters,
         bind(&LegacyNfdc::onSuccess, this, _1, "Nexthop removal succeeded"),
-        bind(&LegacyNfdc::onError, this, _1, _2, "Nexthop removal failed"));
+        bind(&LegacyNfdc::onError, this, _1, "Nexthop removal failed"));
     },
     bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
 }
@@ -159,7 +159,7 @@
 
       m_controller.start<ndn::nfd::RibRegisterCommand>(parameters,
         bind(&LegacyNfdc::onSuccess, this, _1, "Successful in name registration"),
-        bind(&LegacyNfdc::onError, this, _1, _2, "Failed in name registration"));
+        bind(&LegacyNfdc::onError, this, _1, "Failed in name registration"));
     },
     bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
 }
@@ -180,7 +180,7 @@
 
       m_controller.start<ndn::nfd::RibUnregisterCommand>(parameters,
         bind(&LegacyNfdc::onSuccess, this, _1, "Successful in unregistering name"),
-        bind(&LegacyNfdc::onError, this, _1, _2, "Failed in unregistering name"));
+        bind(&LegacyNfdc::onError, this, _1, "Failed in unregistering name"));
     },
     bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
 }
@@ -221,7 +221,7 @@
 
   m_controller.start<ndn::nfd::FaceCreateCommand>(parameters,
     bind(&LegacyNfdc::onSuccess, this, _1, "Face creation succeeded"),
-    bind(&LegacyNfdc::onError, this, _1, _2, "Face creation failed"));
+    bind(&LegacyNfdc::onError, this, _1, "Face creation failed"));
 }
 
 void
@@ -237,7 +237,7 @@
 
       m_controller.start<ndn::nfd::FaceDestroyCommand>(faceParameters,
         bind(&LegacyNfdc::onSuccess, this, _1, "Face destroy succeeded"),
-        bind(&LegacyNfdc::onError, this, _1, _2, "Face destroy failed"));
+        bind(&LegacyNfdc::onError, this, _1, "Face destroy failed"));
     },
     bind(&LegacyNfdc::onObtainFaceIdFailure, this, _1));
 }
@@ -255,7 +255,7 @@
 
   m_controller.start<ndn::nfd::StrategyChoiceSetCommand>(parameters,
     bind(&LegacyNfdc::onSuccess, this, _1, "Successfully set strategy choice"),
-    bind(&LegacyNfdc::onError, this, _1, _2, "Failed to set strategy choice"));
+    bind(&LegacyNfdc::onError, this, _1, "Failed to set strategy choice"));
 }
 
 void
@@ -268,7 +268,7 @@
 
   m_controller.start<ndn::nfd::StrategyChoiceUnsetCommand>(parameters,
     bind(&LegacyNfdc::onSuccess, this, _1, "Successfully unset strategy choice"),
-    bind(&LegacyNfdc::onError, this, _1, _2, "Failed to unset strategy choice"));
+    bind(&LegacyNfdc::onError, this, _1, "Failed to unset strategy choice"));
 }
 
 void
@@ -278,10 +278,10 @@
 }
 
 void
-LegacyNfdc::onError(uint32_t code, const std::string& error, const std::string& message)
+LegacyNfdc::onError(const ndn::nfd::ControlResponse& response, const std::string& message)
 {
   std::ostringstream os;
-  os << message << ": " << error << " (code: " << code << ")";
+  os << message << ": " << response.getText() << " (code: " << response.getCode() << ")";
   BOOST_THROW_EXCEPTION(Error(os.str()));
 }
 
diff --git a/tools/nfdc/legacy-nfdc.hpp b/tools/nfdc/legacy-nfdc.hpp
index 01ed7b9..5a804a1 100644
--- a/tools/nfdc/legacy-nfdc.hpp
+++ b/tools/nfdc/legacy-nfdc.hpp
@@ -142,13 +142,12 @@
   strategyChoiceUnset();
 
 private:
-
   void
   onSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
             const std::string& message);
 
   void
-  onError(uint32_t code, const std::string& error, const std::string& message);
+  onError(const ndn::nfd::ControlResponse& response, const std::string& message);
 
   void
   onCanonizeFailure(const std::string& reason);
diff --git a/tools/nfdc/module.hpp b/tools/nfdc/module.hpp
index f33afac..fae4ce7 100644
--- a/tools/nfdc/module.hpp
+++ b/tools/nfdc/module.hpp
@@ -55,7 +55,7 @@
   virtual void
   fetchStatus(Controller& controller,
               const function<void()>& onSuccess,
-              const Controller::CommandFailCallback& onFailure,
+              const Controller::DatasetFailCallback& onFailure,
               const CommandOptions& options) = 0;
 
   /** \brief format collected status as XML
diff --git a/tools/nfdc/rib-module.cpp b/tools/nfdc/rib-module.cpp
index bf2da3d..266a550 100644
--- a/tools/nfdc/rib-module.cpp
+++ b/tools/nfdc/rib-module.cpp
@@ -33,7 +33,7 @@
 void
 RibModule::fetchStatus(Controller& controller,
                        const function<void()>& onSuccess,
-                       const Controller::CommandFailCallback& onFailure,
+                       const Controller::DatasetFailCallback& onFailure,
                        const CommandOptions& options)
 {
   controller.fetch<ndn::nfd::RibDataset>(
diff --git a/tools/nfdc/rib-module.hpp b/tools/nfdc/rib-module.hpp
index 20e2144..85230aa 100644
--- a/tools/nfdc/rib-module.hpp
+++ b/tools/nfdc/rib-module.hpp
@@ -44,7 +44,7 @@
   virtual void
   fetchStatus(Controller& controller,
               const function<void()>& onSuccess,
-              const Controller::CommandFailCallback& onFailure,
+              const Controller::DatasetFailCallback& onFailure,
               const CommandOptions& options) override;
 
   virtual void
diff --git a/tools/nfdc/strategy-choice-module.cpp b/tools/nfdc/strategy-choice-module.cpp
index c32b5aa..4a6b36f 100644
--- a/tools/nfdc/strategy-choice-module.cpp
+++ b/tools/nfdc/strategy-choice-module.cpp
@@ -33,7 +33,7 @@
 void
 StrategyChoiceModule::fetchStatus(Controller& controller,
                                   const function<void()>& onSuccess,
-                                  const Controller::CommandFailCallback& onFailure,
+                                  const Controller::DatasetFailCallback& onFailure,
                                   const CommandOptions& options)
 {
   controller.fetch<ndn::nfd::StrategyChoiceDataset>(
diff --git a/tools/nfdc/strategy-choice-module.hpp b/tools/nfdc/strategy-choice-module.hpp
index 9c78eb7..4d26896 100644
--- a/tools/nfdc/strategy-choice-module.hpp
+++ b/tools/nfdc/strategy-choice-module.hpp
@@ -43,7 +43,7 @@
   virtual void
   fetchStatus(Controller& controller,
               const function<void()>& onSuccess,
-              const Controller::CommandFailCallback& onFailure,
+              const Controller::DatasetFailCallback& onFailure,
               const CommandOptions& options) override;
 
   virtual void