Enhance exception throwing with Boost Exception library

Change-Id: I471023fc23ffaebe04d9668426b4c1b03e4919aa
Refs: #2541
diff --git a/common.hpp b/common.hpp
index ff9aa2a..5e6724a 100644
--- a/common.hpp
+++ b/common.hpp
@@ -71,6 +71,7 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/property_tree/ptree.hpp>
+#include <boost/throw_exception.hpp>
 
 namespace nfd {
 
diff --git a/core/config-file.cpp b/core/config-file.cpp
index a6861e3..9724168 100644
--- a/core/config-file.cpp
+++ b/core/config-file.cpp
@@ -40,7 +40,7 @@
   msg += filename;
   msg += ": no module subscribed for section \"" + sectionName + "\"";
 
-  throw ConfigFile::Error(msg);
+  BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
 }
 
 void
@@ -73,7 +73,7 @@
     {
       std::string msg = "Failed to read configuration file: ";
       msg += filename;
-      throw Error(msg);
+      BOOST_THROW_EXCEPTION(Error(msg));
     }
   parse(inputFile, isDryRun, filename);
   inputFile.close();
@@ -100,7 +100,7 @@
       msg << "Failed to parse configuration file";
       msg << " " << filename;
       msg << " " << error.message() << " line " << error.line();
-      throw Error(msg.str());
+      BOOST_THROW_EXCEPTION(Error(msg.str()));
     }
 
   process(isDryRun, filename);
@@ -124,7 +124,7 @@
       std::string msg = "Error processing configuration file: ";
       msg += filename;
       msg += " no data";
-      throw Error(msg);
+      BOOST_THROW_EXCEPTION(Error(msg));
     }
 
   for (ConfigSection::const_iterator i = m_global.begin(); i != m_global.end(); ++i)
diff --git a/core/logger-factory.cpp b/core/logger-factory.cpp
index 20578c3..a463b94 100644
--- a/core/logger-factory.cpp
+++ b/core/logger-factory.cpp
@@ -87,7 +87,7 @@
   catch (const boost::bad_lexical_cast& error) {
   }
 
-  throw LoggerFactory::Error("Unsupported logging level \"" + level + "\"");
+  BOOST_THROW_EXCEPTION(LoggerFactory::Error("Unsupported logging level \"" + level + "\""));
 }
 
 LogLevel
@@ -101,7 +101,7 @@
   }
 
   if (levelString.empty()) {
-    throw LoggerFactory::Error("No logging level found for option \"" + key + "\"");
+    BOOST_THROW_EXCEPTION(LoggerFactory::Error("No logging level found for option \"" + key + "\""));
   }
 
   return parseLevel(levelString);
diff --git a/core/network-interface.cpp b/core/network-interface.cpp
index 048b37e..02761a9 100644
--- a/core/network-interface.cpp
+++ b/core/network-interface.cpp
@@ -86,7 +86,8 @@
   ifaddrs* ifa_list = nullptr;
 
   if (::getifaddrs(&ifa_list) < 0)
-    throw std::runtime_error(std::string("getifaddrs() failed: ") + strerror(errno));
+    BOOST_THROW_EXCEPTION(std::runtime_error(std::string("getifaddrs() failed: ") +
+                                             strerror(errno)));
 
   for (ifaddrs* ifa = ifa_list; ifa != nullptr; ifa = ifa->ifa_next) {
     std::string ifname(ifa->ifa_name);
diff --git a/core/privilege-helper.hpp b/core/privilege-helper.hpp
index 380dc64..984532f 100644
--- a/core/privilege-helper.hpp
+++ b/core/privilege-helper.hpp
@@ -36,8 +36,10 @@
 {
 public:
 
-  /// \brief PrivilegeHelper::Error represents a serious seteuid/gid failure and
-  ///        should only be caught by main in as part of a graceful program termination.
+  /** \brief represents a serious seteuid/gid failure
+   *  \detail This should only be caught by main in as part of a graceful program termination.
+   *  \note This is not an std::exception and BOOST_THROW_EXCEPTION should not be used.
+   */
   class Error
   {
   public:
diff --git a/daemon/face/ethernet-face.cpp b/daemon/face/ethernet-face.cpp
index 856213c..f31a8f6 100644
--- a/daemon/face/ethernet-face.cpp
+++ b/daemon/face/ethernet-face.cpp
@@ -83,7 +83,7 @@
 
   int fd = pcap_get_selectable_fd(m_pcap.get());
   if (fd < 0)
-    throw Error("pcap_get_selectable_fd failed");
+    BOOST_THROW_EXCEPTION(Error("pcap_get_selectable_fd failed"));
 
   // need to duplicate the fd, otherwise both pcap_close()
   // and stream_descriptor::close() will try to close the
@@ -165,7 +165,7 @@
   char errbuf[PCAP_ERRBUF_SIZE] = {};
   m_pcap.reset(pcap_create(m_interfaceName.c_str(), errbuf));
   if (!m_pcap)
-    throw Error("pcap_create: " + std::string(errbuf));
+    BOOST_THROW_EXCEPTION(Error("pcap_create: " + std::string(errbuf)));
 
 #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
   // Enable "immediate mode", effectively disabling any read buffering in the kernel.
@@ -176,10 +176,10 @@
 #endif
 
   if (pcap_activate(m_pcap.get()) < 0)
-    throw Error("pcap_activate failed");
+    BOOST_THROW_EXCEPTION(Error("pcap_activate failed"));
 
   if (pcap_set_datalink(m_pcap.get(), DLT_EN10MB) < 0)
-    throw Error("pcap_set_datalink: " + std::string(pcap_geterr(m_pcap.get())));
+    BOOST_THROW_EXCEPTION(Error("pcap_set_datalink: " + std::string(pcap_geterr(m_pcap.get()))));
 
   if (pcap_setdirection(m_pcap.get(), PCAP_D_IN) < 0)
     // no need to throw on failure, BPF will filter unwanted packets anyway
@@ -191,12 +191,12 @@
 {
   bpf_program filter;
   if (pcap_compile(m_pcap.get(), &filter, filterString, 1, PCAP_NETMASK_UNKNOWN) < 0)
-    throw Error("pcap_compile: " + std::string(pcap_geterr(m_pcap.get())));
+    BOOST_THROW_EXCEPTION(Error("pcap_compile: " + std::string(pcap_geterr(m_pcap.get()))));
 
   int ret = pcap_setfilter(m_pcap.get(), &filter);
   pcap_freecode(&filter);
   if (ret < 0)
-    throw Error("pcap_setfilter: " + std::string(pcap_geterr(m_pcap.get())));
+    BOOST_THROW_EXCEPTION(Error("pcap_setfilter: " + std::string(pcap_geterr(m_pcap.get()))));
 }
 
 bool
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index 9387fe6..63f428c 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -36,7 +36,7 @@
                                      const ethernet::Address &address)
 {
   if (!address.isMulticast())
-    throw Error(address.toString() + " is not a multicast address");
+    BOOST_THROW_EXCEPTION(Error(address.toString() + " is not a multicast address"));
 
   shared_ptr<EthernetFace> face = findMulticastFace(interface.name, address);
   if (face)
@@ -71,7 +71,7 @@
                             const FaceCreatedCallback& onCreated,
                             const FaceConnectFailedCallback& onConnectFailed)
 {
-  throw Error("EthernetFactory does not support 'createFace' operation");
+  BOOST_THROW_EXCEPTION(Error("EthernetFactory does not support 'createFace' operation"));
 }
 
 std::list<shared_ptr<const Channel>>
diff --git a/daemon/face/ndnlp-sequence-generator.hpp b/daemon/face/ndnlp-sequence-generator.hpp
index a3baa6b..3019933 100644
--- a/daemon/face/ndnlp-sequence-generator.hpp
+++ b/daemon/face/ndnlp-sequence-generator.hpp
@@ -54,7 +54,7 @@
 SequenceBlock::operator[](size_t pos) const
 {
   if (pos >= m_count)
-    throw std::out_of_range("pos");
+    BOOST_THROW_EXCEPTION(std::out_of_range("pos"));
   return m_start + static_cast<uint64_t>(pos);
 }
 
diff --git a/daemon/face/tcp-face.hpp b/daemon/face/tcp-face.hpp
index f77b72d..4313c06 100644
--- a/daemon/face/tcp-face.hpp
+++ b/daemon/face/tcp-face.hpp
@@ -69,7 +69,8 @@
     if (!socket.local_endpoint().address().is_loopback() ||
         !socket.remote_endpoint().address().is_loopback())
       {
-        throw Face::Error("TcpLocalFace can be created only on a loopback address");
+        BOOST_THROW_EXCEPTION(Face::Error("TcpLocalFace can be created only on a loopback "
+                                          "address"));
       }
   }
 };
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index 9c640a1..4fb6059 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -132,7 +132,7 @@
                        const FaceConnectFailedCallback& onConnectFailed)
 {
   if (persistency != ndn::nfd::FACE_PERSISTENCY_PERSISTENT) {
-    throw Error("TcpFactory only supports persistent face");
+    BOOST_THROW_EXCEPTION(Error("TcpFactory only supports persistent face"));
   }
 
   BOOST_ASSERT(uri.isCanonical());
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 3a55b7c..07b0367 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -120,13 +120,13 @@
   //checking if the endpoint is already in use for multicast face
   shared_ptr<MulticastUdpFace> multicast = findMulticastFace(endpoint);
   if (static_cast<bool>(multicast))
-    throw Error("Cannot create the requested UDP unicast channel, local "
-                "endpoint is already allocated for a UDP multicast face");
+    BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP unicast channel, local "
+                                "endpoint is already allocated for a UDP multicast face"));
 
   if (endpoint.address().is_multicast()) {
-    throw Error("This method is only for unicast channel. The provided "
-                "endpoint is multicast. Use createMulticastFace to "
-                "create a multicast face");
+    BOOST_THROW_EXCEPTION(Error("This method is only for unicast channel. The provided "
+                                "endpoint is multicast. Use createMulticastFace to "
+                                "create a multicast face"));
   }
 
   channel = make_shared<UdpChannel>(endpoint, timeout);
@@ -157,35 +157,36 @@
     if (face->getMulticastGroup() == multicastEndpoint)
       return face;
     else
-      throw Error("Cannot create the requested UDP multicast face, local "
-                  "endpoint is already allocated for a UDP multicast face "
-                  "on a different multicast group");
+      BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, local "
+                                  "endpoint is already allocated for a UDP multicast face "
+                                  "on a different multicast group"));
   }
 
   // checking if the local endpoint is already in use for a unicast channel
   shared_ptr<UdpChannel> unicast = findChannel(localEndpoint);
   if (static_cast<bool>(unicast)) {
-    throw Error("Cannot create the requested UDP multicast face, local "
-                "endpoint is already allocated for a UDP unicast channel");
+    BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, local "
+                                "endpoint is already allocated for a UDP unicast channel"));
   }
 
   if (m_prohibitedEndpoints.find(multicastEndpoint) != m_prohibitedEndpoints.end()) {
-    throw Error("Cannot create the requested UDP multicast face, "
-                "remote endpoint is owned by this NFD instance");
+    BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, "
+                                "remote endpoint is owned by this NFD instance"));
   }
 
   if (localEndpoint.address().is_v6() || multicastEndpoint.address().is_v6()) {
-    throw Error("IPv6 multicast is not supported yet. Please provide an IPv4 address");
+    BOOST_THROW_EXCEPTION(Error("IPv6 multicast is not supported yet. Please provide an IPv4 "
+                                "address"));
   }
 
   if (localEndpoint.port() != multicastEndpoint.port()) {
-    throw Error("Cannot create the requested UDP multicast face, "
-                "both endpoints should have the same port number. ");
+    BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, "
+                                "both endpoints should have the same port number. "));
   }
 
   if (!multicastEndpoint.address().is_multicast()) {
-    throw Error("Cannot create the requested UDP multicast face, "
-                "the multicast group given as input is not a multicast address");
+    BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, "
+                                "the multicast group given as input is not a multicast address"));
   }
 
   ip::udp::socket receiveSocket(getGlobalIoService());
@@ -218,8 +219,8 @@
   if (!networkInterfaceName.empty()) {
     if (::setsockopt(receiveSocket.native_handle(), SOL_SOCKET, SO_BINDTODEVICE,
                      networkInterfaceName.c_str(), networkInterfaceName.size() + 1) < 0) {
-      throw Error("Cannot bind multicast face to " + networkInterfaceName +
-                  ": " + std::strerror(errno));
+      BOOST_THROW_EXCEPTION(Error("Cannot bind multicast face to " + networkInterfaceName +
+                                  ": " + std::strerror(errno)));
     }
   }
 #endif
@@ -255,7 +256,7 @@
                        const FaceConnectFailedCallback& onConnectFailed)
 {
   if (persistency != ndn::nfd::FACE_PERSISTENCY_PERSISTENT) {
-    throw Error("UdpFactory only supports persistent face");
+    BOOST_THROW_EXCEPTION(Error("UdpFactory only supports persistent face"));
   }
 
   BOOST_ASSERT(uri.isCanonical());
diff --git a/daemon/face/unix-stream-channel.cpp b/daemon/face/unix-stream-channel.cpp
index ece6d0e..c883163 100644
--- a/daemon/face/unix-stream-channel.cpp
+++ b/daemon/face/unix-stream-channel.cpp
@@ -77,8 +77,8 @@
                   + error.message());
     if (!error) {
       // someone answered, leave the socket alone
-      throw Error("Socket file at " + m_endpoint.path()
-                  + " belongs to another NFD process");
+      BOOST_THROW_EXCEPTION(Error("Socket file at " + m_endpoint.path()
+                                  + " belongs to another NFD process"));
     }
     else if (error == boost::asio::error::connection_refused ||
              error == boost::asio::error::timed_out) {
@@ -89,7 +89,7 @@
     }
   }
   else if (type != fs::file_not_found) {
-    throw Error(m_endpoint.path() + " already exists and is not a socket file");
+    BOOST_THROW_EXCEPTION(Error(m_endpoint.path() + " already exists and is not a socket file"));
   }
 
   m_acceptor.open();
@@ -97,7 +97,8 @@
   m_acceptor.listen(backlog);
 
   if (::chmod(m_endpoint.path().c_str(), 0666) < 0) {
-    throw Error("chmod(" + m_endpoint.path() + ") failed: " + std::strerror(errno));
+    BOOST_THROW_EXCEPTION(Error("chmod(" + m_endpoint.path() + ") failed: " +
+                                std::strerror(errno)));
   }
 
   // start accepting connections
diff --git a/daemon/face/unix-stream-factory.cpp b/daemon/face/unix-stream-factory.cpp
index 16a01a9..717f7b6 100644
--- a/daemon/face/unix-stream-factory.cpp
+++ b/daemon/face/unix-stream-factory.cpp
@@ -61,7 +61,7 @@
                               const FaceCreatedCallback& onCreated,
                               const FaceConnectFailedCallback& onConnectFailed)
 {
-  throw Error("UnixStreamFactory does not support 'createFace' operation");
+  BOOST_THROW_EXCEPTION(Error("UnixStreamFactory does not support 'createFace' operation"));
 }
 
 std::list<shared_ptr<const Channel> >
diff --git a/daemon/face/websocket-factory.cpp b/daemon/face/websocket-factory.cpp
index e911827..80e8efa 100644
--- a/daemon/face/websocket-factory.cpp
+++ b/daemon/face/websocket-factory.cpp
@@ -71,7 +71,7 @@
                              const FaceCreatedCallback& onCreated,
                              const FaceConnectFailedCallback& onConnectFailed)
 {
-  throw Error("WebSocketFactory does not support 'createFace' operation");
+  BOOST_THROW_EXCEPTION(Error("WebSocketFactory does not support 'createFace' operation"));
 }
 
 std::list<shared_ptr<const Channel> >
diff --git a/daemon/main.cpp b/daemon/main.cpp
index e6b9ae7..6646240 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -240,10 +240,12 @@
 
   po::variables_map vm;
   try {
-      po::store(po::command_line_parser(argc, argv).options(description).run(), vm);
-      po::notify(vm);
+    po::store(po::command_line_parser(argc, argv).options(description).run(), vm);
+    po::notify(vm);
   }
   catch (const std::exception& e) {
+    // avoid NFD_LOG_FATAL to ensure that errors related to command-line parsing always appear on the
+    // terminal and are not littered with timestamps and other things added by the logging subsystem
     std::cerr << "ERROR: " << e.what() << std::endl;
     NfdRunner::printUsage(std::cerr, argv[0]);
     return 1;
@@ -273,11 +275,12 @@
     if (e.code() == boost::system::errc::permission_denied) {
       NFD_LOG_FATAL("Permissions denied for " << e.path1() << ". " <<
                     argv[0] << " should be run as superuser");
+      return 3;
     }
     else {
       NFD_LOG_FATAL(e.what());
+      return 2;
     }
-    return 1;
   }
   catch (const std::exception& e) {
     NFD_LOG_FATAL(e.what());
diff --git a/daemon/mgmt/command-validator.cpp b/daemon/mgmt/command-validator.cpp
index 396cfe4..715b5d5 100644
--- a/daemon/mgmt/command-validator.cpp
+++ b/daemon/mgmt/command-validator.cpp
@@ -75,7 +75,7 @@
 
   if (section.begin() == section.end())
     {
-      throw ConfigFile::Error("No authorize sections found");
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("No authorize sections found"));
     }
 
   std::stringstream dryRunErrors;
@@ -92,7 +92,7 @@
           std::string msg = "No certfile specified";
           if (!isDryRun)
             {
-              throw ConfigFile::Error(msg);
+              BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
             }
           aggregateErrors(dryRunErrors, msg);
           continue;
@@ -112,7 +112,7 @@
               std::string msg = "Unable to open certificate file " + certfilePath.native();
               if (!isDryRun)
                 {
-                  throw ConfigFile::Error(msg);
+                  BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
                 }
               aggregateErrors(dryRunErrors, msg);
               continue;
@@ -131,7 +131,7 @@
             std::string msg = "Malformed certificate file " + certfilePath.native();
             if (!isDryRun)
               {
-                throw ConfigFile::Error(msg);
+                BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
               }
             aggregateErrors(dryRunErrors, msg);
             continue;
@@ -160,7 +160,7 @@
             certfile + " (" + keyNameForLogging + ")";
           if (!isDryRun)
             {
-              throw ConfigFile::Error(msg);
+              BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
             }
           aggregateErrors(dryRunErrors, msg);
           continue;
@@ -196,7 +196,7 @@
                 "\" for certificate file " + certfile + " (" + keyNameForLogging + ")";
               if (!isDryRun)
                 {
-                  throw ConfigFile::Error(msg);
+                  BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
                 }
               aggregateErrors(dryRunErrors, msg);
             }
@@ -205,7 +205,7 @@
 
   if (!dryRunErrors.str().empty())
     {
-      throw ConfigFile::Error(dryRunErrors.str());
+      BOOST_THROW_EXCEPTION(ConfigFile::Error(dryRunErrors.str()));
     }
 }
 
@@ -214,7 +214,7 @@
 {
   if (m_supportedPrivileges.find(privilege) != m_supportedPrivileges.end())
     {
-      throw CommandValidator::Error("Duplicated privilege: " + privilege);
+      BOOST_THROW_EXCEPTION(CommandValidator::Error("Duplicated privilege: " + privilege));
     }
   m_supportedPrivileges.insert(privilege);
 }
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index eecf25c..692acf9 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -173,7 +173,7 @@
       if (item.first == "unix")
         {
           if (hasSeenUnix)
-            throw Error("Duplicate \"unix\" section");
+            BOOST_THROW_EXCEPTION(Error("Duplicate \"unix\" section"));
           hasSeenUnix = true;
 
           processSectionUnix(item.second, isDryRun);
@@ -181,7 +181,7 @@
       else if (item.first == "tcp")
         {
           if (hasSeenTcp)
-            throw Error("Duplicate \"tcp\" section");
+            BOOST_THROW_EXCEPTION(Error("Duplicate \"tcp\" section"));
           hasSeenTcp = true;
 
           processSectionTcp(item.second, isDryRun);
@@ -189,7 +189,7 @@
       else if (item.first == "udp")
         {
           if (hasSeenUdp)
-            throw Error("Duplicate \"udp\" section");
+            BOOST_THROW_EXCEPTION(Error("Duplicate \"udp\" section"));
           hasSeenUdp = true;
 
           processSectionUdp(item.second, isDryRun, nicList);
@@ -197,7 +197,7 @@
       else if (item.first == "ether")
         {
           if (hasSeenEther)
-            throw Error("Duplicate \"ether\" section");
+            BOOST_THROW_EXCEPTION(Error("Duplicate \"ether\" section"));
           hasSeenEther = true;
 
           processSectionEther(item.second, isDryRun, nicList);
@@ -205,14 +205,14 @@
       else if (item.first == "websocket")
         {
           if (hasSeenWebSocket)
-            throw Error("Duplicate \"websocket\" section");
+            BOOST_THROW_EXCEPTION(Error("Duplicate \"websocket\" section"));
           hasSeenWebSocket = true;
 
           processSectionWebSocket(item.second, isDryRun);
         }
       else
         {
-          throw Error("Unrecognized option \"" + item.first + "\"");
+          BOOST_THROW_EXCEPTION(Error("Unrecognized option \"" + item.first + "\""));
         }
     }
 }
@@ -240,7 +240,8 @@
         }
       else
         {
-          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"unix\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first + "\" in "
+                                                  "\"unix\" section"));
         }
     }
 
@@ -269,8 +270,8 @@
       m_factories.insert(std::make_pair("unix", factory));
     }
 #else
-  throw ConfigFile::Error("NFD was compiled without Unix sockets support, "
-                          "cannot process \"unix\" section");
+  BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without Unix sockets support, "
+                                          "cannot process \"unix\" section"));
 #endif // HAVE_UNIX_SOCKETS
 
 }
@@ -304,8 +305,8 @@
             }
           catch (const std::bad_cast& error)
             {
-              throw ConfigFile::Error("Invalid value for option " +
-                                      i->first + "\" in \"tcp\" section");
+              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                      i->first + "\" in \"tcp\" section"));
             }
         }
       else if (i->first == "listen")
@@ -322,15 +323,16 @@
         }
       else
         {
-          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"tcp\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first + "\" in "
+                                                  "\"tcp\" section"));
         }
     }
 
   if (!enableV4 && !enableV6)
     {
-      throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
-                              " Remove \"tcp\" section to disable TCP channels or"
-                              " re-enable at least one channel type.");
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+                                              " Remove \"tcp\" section to disable TCP channels or"
+                                              " re-enable at least one channel type."));
     }
 
   if (!isDryRun)
@@ -413,8 +415,8 @@
             }
           catch (const std::bad_cast& error)
             {
-              throw ConfigFile::Error("Invalid value for option " +
-                                      i->first + "\" in \"udp\" section");
+              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                      i->first + "\" in \"udp\" section"));
             }
         }
       else if (i->first == "enable_v4")
@@ -433,8 +435,8 @@
             }
           catch (const std::exception& e)
             {
-              throw ConfigFile::Error("Invalid value for option \"" +
-                                      i->first + "\" in \"udp\" section");
+              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                      i->first + "\" in \"udp\" section"));
             }
         }
       else if (i->first == "keep_alive_interval")
@@ -448,8 +450,8 @@
             }
           catch (const std::exception& e)
             {
-              throw ConfigFile::Error("Invalid value for option \"" +
-                                      i->first + "\" in \"udp\" section");
+              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                      i->first + "\" in \"udp\" section"));
             }
         }
       else if (i->first == "mcast")
@@ -466,8 +468,8 @@
             }
           catch (const std::bad_cast& error)
             {
-              throw ConfigFile::Error("Invalid value for option " +
-                                      i->first + "\" in \"udp\" section");
+              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                      i->first + "\" in \"udp\" section"));
             }
         }
       else if (i->first == "mcast_group")
@@ -479,32 +481,34 @@
               address mcastGroupTest = address::from_string(mcastGroup);
               if (!mcastGroupTest.is_v4())
                 {
-                  throw ConfigFile::Error("Invalid value for option \"" +
-                                          i->first + "\" in \"udp\" section");
+                  BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                          i->first + "\" in \"udp\" section"));
                 }
             }
           catch(const std::runtime_error& e)
             {
-              throw ConfigFile::Error("Invalid value for option \"" +
-                                      i->first + "\" in \"udp\" section");
+              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                      i->first + "\" in \"udp\" section"));
             }
         }
       else
         {
-          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"udp\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first + "\" in "
+                                                  "\"udp\" section"));
         }
     }
 
   if (!enableV4 && !enableV6)
     {
-      throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
-                              " Remove \"udp\" section to disable UDP channels or"
-                              " re-enable at least one channel type.");
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+                                              " Remove \"udp\" section to disable UDP channels or"
+                                              " re-enable at least one channel type."));
     }
   else if (useMcast && !enableV4)
     {
-      throw ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
-                              " have been disabled (conflicting configuration options set)");
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
+                                              " have been disabled (conflicting configuration"
+                                              " options set)"));
     }
 
   /// \todo what is keep alive interval used for?
@@ -645,13 +649,14 @@
           mcastGroup = ethernet::Address::fromString(i->second.get_value<std::string>());
           if (mcastGroup.isNull())
             {
-              throw ConfigFile::Error("Invalid value for option \"" +
-                                      i->first + "\" in \"ether\" section");
+              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                      i->first + "\" in \"ether\" section"));
             }
         }
       else
         {
-          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"ether\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i->first +
+                                                  "\" in \"ether\" section"));
         }
     }
 
@@ -729,7 +734,8 @@
         }
     }
 #else
-  throw ConfigFile::Error("NFD was compiled without libpcap, cannot process \"ether\" section");
+  BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without libpcap, cannot "
+                                          "process \"ether\" section"));
 #endif // HAVE_LIBPCAP
 }
 
@@ -766,8 +772,8 @@
             }
           catch (const std::bad_cast& error)
             {
-              throw ConfigFile::Error("Invalid value for option " +
-                                      i->first + "\" in \"websocket\" section");
+              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                      i->first + "\" in \"websocket\" section"));
             }
         }
       else if (i->first == "listen")
@@ -784,21 +790,21 @@
         }
       else
         {
-          throw ConfigFile::Error("Unrecognized option \"" +
-                                  i->first + "\" in \"websocket\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                                  i->first + "\" in \"websocket\" section"));
         }
     }
 
   if (!enableV4 && !enableV6)
     {
-      throw ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
-                              " Remove \"websocket\" section to disable WebSocket channels or"
-                              " re-enable at least one channel type.");
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+                                              " Remove \"websocket\" section to disable WebSocket"
+                                              " channels or re-enable at least one channel type."));
     }
 
   if (!enableV4 && enableV6)
     {
-      throw ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel.");
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel."));
     }
 
   if (!isDryRun)
@@ -833,8 +839,8 @@
         }
     }
 #else
-  throw ConfigFile::Error("NFD was compiled without WebSocket, "
-                          "cannot process \"websocket\" section");
+  BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without WebSocket, "
+                                          "cannot process \"websocket\" section"));
 #endif // HAVE_WEBSOCKET
 }
 
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
index 75477bf..74dc0dd 100644
--- a/daemon/mgmt/face-manager.hpp
+++ b/daemon/mgmt/face-manager.hpp
@@ -234,9 +234,9 @@
       return false;
     }
 
-  throw ConfigFile::Error("Invalid value for option \"" +
-                          optionName + "\" in \"" +
-                          sectionName + "\" section");
+   BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                           optionName + "\" in \"" +
+                                           sectionName + "\" section"));
 }
 
 inline void
diff --git a/daemon/mgmt/general-config-section.cpp b/daemon/mgmt/general-config-section.cpp
index 4064548..ce58909 100644
--- a/daemon/mgmt/general-config-section.cpp
+++ b/daemon/mgmt/general-config-section.cpp
@@ -73,14 +73,14 @@
 
       if (value.empty())
         {
-          throw ConfigFile::Error("Invalid value for \"router_name." + key + "\""
-                                  " in \"general\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"router_name." + key + "\""
+                                                  " in \"general\" section"));
         }
     }
   catch (const boost::property_tree::ptree_error& error)
     {
-      throw ConfigFile::Error("Invalid value for \"router_name." + key + "\""
-                              " in \"general\" section");
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"router_name." + key + "\""
+                                              " in \"general\" section"));
     }
 
   return value;
@@ -129,14 +129,14 @@
 
               if (user.empty())
                 {
-                  throw ConfigFile::Error("Invalid value for \"user\""
-                                          " in \"general\" section");
+                  BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"user\""
+                                                          " in \"general\" section"));
                 }
             }
           catch (const boost::property_tree::ptree_error& error)
             {
-              throw ConfigFile::Error("Invalid value for \"user\""
-                                      " in \"general\" section");
+              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"user\""
+                                                      " in \"general\" section"));
             }
         }
       else if (i->first == "group")
@@ -147,14 +147,14 @@
 
               if (group.empty())
                 {
-                  throw ConfigFile::Error("Invalid value for \"group\""
-                                          " in \"general\" section");
+                  BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"group\""
+                                                          " in \"general\" section"));
                 }
             }
           catch (const boost::property_tree::ptree_error& error)
             {
-              throw ConfigFile::Error("Invalid value for \"group\""
-                                      " in \"general\" section");
+              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"group\""
+                                                      " in \"general\" section"));
             }
         }
     }
diff --git a/daemon/mgmt/internal-face.cpp b/daemon/mgmt/internal-face.cpp
index ec142ef..7569fb9 100644
--- a/daemon/mgmt/internal-face.cpp
+++ b/daemon/mgmt/internal-face.cpp
@@ -128,7 +128,7 @@
 void
 InternalFace::close()
 {
-  throw Error("Internal face cannot be closed");
+  BOOST_THROW_EXCEPTION(Error("Internal face cannot be closed"));
 }
 
 void
diff --git a/daemon/mgmt/tables-config-section.cpp b/daemon/mgmt/tables-config-section.cpp
index 861ed7f..c7661ce 100644
--- a/daemon/mgmt/tables-config-section.cpp
+++ b/daemon/mgmt/tables-config-section.cpp
@@ -102,8 +102,8 @@
 
       if (!valCsMaxPackets)
         {
-          throw ConfigFile::Error("Invalid value for option \"cs_max_packets\""
-                                  " in \"tables\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"cs_max_packets\""
+                                                  " in \"tables\" section"));
         }
 
       nCsMaxPackets = *valCsMaxPackets;
@@ -145,23 +145,26 @@
       const Name prefix(prefixAndStrategy.first);
       if (choices.find(prefix) != choices.end())
         {
-          throw ConfigFile::Error("Duplicate strategy choice for prefix \"" +
-                                  prefix.toUri() + "\" in \"strategy_choice\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Duplicate strategy choice for prefix \"" +
+                                                  prefix.toUri() + "\" in \"strategy_choice\" "
+                                                  "section"));
         }
 
       const std::string strategyString(prefixAndStrategy.second.get_value<std::string>());
       if (strategyString.empty())
         {
-          throw ConfigFile::Error("Invalid strategy choice \"\" for prefix \"" +
-                                  prefix.toUri() + "\" in \"strategy_choice\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid strategy choice \"\" for prefix \"" +
+                                                  prefix.toUri() + "\" in \"strategy_choice\" "
+                                                  "section"));
         }
 
       const Name strategyName(strategyString);
       if (!m_strategyChoice.hasStrategy(strategyName))
         {
-          throw ConfigFile::Error("Invalid strategy choice \"" +
-                                  strategyName.toUri() + "\" for prefix \"" +
-                                  prefix.toUri() + "\" in \"strategy_choice\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid strategy choice \"" +
+                                                  strategyName.toUri() + "\" for prefix \"" +
+                                                  prefix.toUri() + "\" in \"strategy_choice\" "
+                                                  "section"));
         }
 
       choices[prefix] = strategyName;
@@ -172,9 +175,10 @@
     {
       if (!isDryRun && !m_strategyChoice.insert(prefixAndStrategy.first, prefixAndStrategy.second))
         {
-          throw ConfigFile::Error("Failed to set strategy \"" +
-                                  prefixAndStrategy.second.toUri() + "\" for prefix \"" +
-                                  prefixAndStrategy.first.toUri() + "\" in \"strategy_choicev\"");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Failed to set strategy \"" +
+                                                  prefixAndStrategy.second.toUri() + "\" for "
+                                                  "prefix \"" + prefixAndStrategy.first.toUri() +
+                                                  "\" in \"strategy_choicev\""));
         }
     }
 }
diff --git a/daemon/table/dead-nonce-list.cpp b/daemon/table/dead-nonce-list.cpp
index ceaa218..5df2482 100644
--- a/daemon/table/dead-nonce-list.cpp
+++ b/daemon/table/dead-nonce-list.cpp
@@ -51,7 +51,7 @@
   , m_adjustCapacityInterval(m_lifetime)
 {
   if (m_lifetime < MIN_LIFETIME) {
-    throw std::invalid_argument("lifetime is less than MIN_LIFETIME");
+    BOOST_THROW_EXCEPTION(std::invalid_argument("lifetime is less than MIN_LIFETIME"));
   }
 
   for (size_t i = 0; i < EXPECTED_MARK_COUNT; ++i) {
diff --git a/rib/fib-updater.cpp b/rib/fib-updater.cpp
index 8d581be..91d1bdd 100644
--- a/rib/fib-updater.cpp
+++ b/rib/fib-updater.cpp
@@ -305,7 +305,8 @@
     }
   }
   else {
-    throw Error("Non-recoverable error: " + error + " code: " + std::to_string(code));
+    BOOST_THROW_EXCEPTION(Error("Non-recoverable error: " + error + " code: " +
+                                std::to_string(code)));
   }
 }
 
diff --git a/rib/nrd.cpp b/rib/nrd.cpp
index bdfab99..bcee83c 100644
--- a/rib/nrd.cpp
+++ b/rib/nrd.cpp
@@ -143,7 +143,7 @@
     return make_shared<ndn::TcpTransport>("localhost", port);
   }
   else {
-    throw Error("No transport is available to communicate with NFD");
+    BOOST_THROW_EXCEPTION(Error("No transport is available to communicate with NFD"));
   }
 }
 
diff --git a/rib/remote-registrator.cpp b/rib/remote-registrator.cpp
index aa45269..d33ba1b 100644
--- a/rib/remote-registrator.cpp
+++ b/rib/remote-registrator.cpp
@@ -90,8 +90,8 @@
         }
       else
         {
-          throw ConfigFile::Error("Unrecognized option \"" + i.first +
-                                  "\" in \"remote-registrator\" section");
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" + i.first +
+                                                  "\" in \"remote-registrator\" section"));
         }
     }
 
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
index 4c03f3b..91f0eda 100644
--- a/rib/rib-manager.cpp
+++ b/rib/rib-manager.cpp
@@ -167,7 +167,7 @@
       m_remoteRegistrator.enable();
     }
     else {
-      throw Error("Unrecognized rib property: " + item.first);
+      BOOST_THROW_EXCEPTION(Error("Unrecognized rib property: " + item.first));
     }
   }
 
@@ -571,7 +571,7 @@
 void
 RibManager::onNrdCommandPrefixAddNextHopError(const Name& name, const std::string& msg)
 {
-  throw Error("Error in setting interest filter (" + name.toUri() + "): " + msg);
+  BOOST_THROW_EXCEPTION(Error("Error in setting interest filter (" + name.toUri() + "): " + msg));
 }
 
 void
@@ -586,7 +586,7 @@
   std::ostringstream os;
   os << "Couldn't enable local control header "
      << "(code: " << code << ", info: " << reason << ")";
-  throw Error(os.str());
+  BOOST_THROW_EXCEPTION(Error(os.str()));
 }
 
 void
diff --git a/tests/core/simple-notification.hpp b/tests/core/simple-notification.hpp
index aad86e6..44c0be5 100644
--- a/tests/core/simple-notification.hpp
+++ b/tests/core/simple-notification.hpp
@@ -65,7 +65,7 @@
 
     // error for testing
     if (!m_message.empty() && m_message[0] == '\x07')
-      throw tlv::Error("0x07 error");
+      BOOST_THROW_EXCEPTION(tlv::Error("0x07 error"));
   }
 
 public:
diff --git a/tests/daemon/face/dummy-stream-sender.hpp b/tests/daemon/face/dummy-stream-sender.hpp
index af0e114..7cbb4e2 100644
--- a/tests/daemon/face/dummy-stream-sender.hpp
+++ b/tests/daemon/face/dummy-stream-sender.hpp
@@ -67,7 +67,7 @@
   {
     if (error)
       {
-        throw Error("Connection aborted");
+        BOOST_THROW_EXCEPTION(Error("Connection aborted"));
       }
 
     // This value may need to be adjusted if some dataset exceeds 100k
@@ -88,7 +88,7 @@
   onSendFinished(const boost::system::error_code& error, bool isFinal)
   {
     if (error) {
-      throw Error("Connection aborted");
+      BOOST_THROW_EXCEPTION(Error("Connection aborted"));
     }
 
     if (isFinal) {
diff --git a/tests/daemon/mgmt/face-status-publisher-common.hpp b/tests/daemon/mgmt/face-status-publisher-common.hpp
index d785149..882c976 100644
--- a/tests/daemon/mgmt/face-status-publisher-common.hpp
+++ b/tests/daemon/mgmt/face-status-publisher-common.hpp
@@ -82,7 +82,7 @@
     }
   std::stringstream error;
   error << "expected type " << type << " got " << block.type();
-  throw tlv::Error(error.str());
+  BOOST_THROW_EXCEPTION(tlv::Error(error.str()));
 }
 
 static inline uint64_t
@@ -96,7 +96,7 @@
       ++i;
       return readNonNegativeIntegerType(block, type);
     }
-  throw tlv::Error("Unexpected end of FaceStatus");
+  BOOST_THROW_EXCEPTION(tlv::Error("Unexpected end of FaceStatus"));
 }
 
 class FaceStatusPublisherFixture : public BaseFixture
diff --git a/tests/daemon/mgmt/fib-enumeration-publisher-common.hpp b/tests/daemon/mgmt/fib-enumeration-publisher-common.hpp
index cbb7280..9f9150b 100644
--- a/tests/daemon/mgmt/fib-enumeration-publisher-common.hpp
+++ b/tests/daemon/mgmt/fib-enumeration-publisher-common.hpp
@@ -51,7 +51,7 @@
     }
   std::stringstream error;
   error << "Expected type " << type << " got " << block.type();
-  throw tlv::Error(error.str());
+  BOOST_THROW_EXCEPTION(tlv::Error(error.str()));
 }
 
 static inline uint64_t
@@ -68,7 +68,7 @@
   std::stringstream error;
   error << "Unexpected end of Block while attempting to read type #"
         << type;
-  throw tlv::Error(error.str());
+  BOOST_THROW_EXCEPTION(tlv::Error(error.str()));
 }
 
 class FibEnumerationPublisherFixture : public BaseFixture
diff --git a/tests/limited-io.cpp b/tests/limited-io.cpp
index 4bfd802..ec62041 100644
--- a/tests/limited-io.cpp
+++ b/tests/limited-io.cpp
@@ -101,7 +101,7 @@
     m_reason = EXCEED_OPS;
     getGlobalIoService().stop();
     if (m_uttf != nullptr) {
-      throw StopException();
+      BOOST_THROW_EXCEPTION(StopException());
     }
   }
 }
@@ -112,7 +112,7 @@
   m_reason = EXCEED_TIME;
   getGlobalIoService().stop();
   if (m_uttf != nullptr) {
-    throw StopException();
+    BOOST_THROW_EXCEPTION(StopException());
   }
 }
 
diff --git a/tests/limited-io.hpp b/tests/limited-io.hpp
index 3e4be61..437335c 100644
--- a/tests/limited-io.hpp
+++ b/tests/limited-io.hpp
@@ -87,7 +87,7 @@
 private:
   /** \brief an exception to stop IO operation
    */
-  class StopException
+  class StopException : public std::exception
   {
   };
 
diff --git a/tools/ndn-autoconfig/base-dns.cpp b/tools/ndn-autoconfig/base-dns.cpp
index 60eed48..bcd1f65 100644
--- a/tools/ndn-autoconfig/base-dns.cpp
+++ b/tools/ndn-autoconfig/base-dns.cpp
@@ -68,7 +68,7 @@
                              queryAnswer.buf,
                              sizeof(queryAnswer));
   if (answerSize == 0) {
-    throw Error("No DNS SRV records found for " + srvDomain);
+    BOOST_THROW_EXCEPTION(Error("No DNS SRV records found for " + srvDomain));
   }
   return parseSrvRr(queryAnswer, answerSize);
 }
@@ -96,7 +96,7 @@
                               sizeof(queryAnswer));
 
   if (answerSize == 0) {
-    throw Error("No DNS SRV records found for _ndn._udp");
+    BOOST_THROW_EXCEPTION(Error("No DNS SRV records found for _ndn._udp"));
   }
 
   return parseSrvRr(queryAnswer, answerSize);
@@ -125,7 +125,7 @@
   };
 
   if (ntohs(queryAnswer.header.ancount) == 0) {
-    throw Error("SRV record cannot be parsed");
+    BOOST_THROW_EXCEPTION(Error("SRV record cannot be parsed"));
   }
 
   const uint8_t* blob = queryAnswer.buf + NS_HFIXEDSZ;
@@ -139,7 +139,7 @@
                                  srvName,                       // expanded server name
                                  NS_MAXDNAME);
   if (serverNameSize <= 0) {
-    throw Error("SRV record cannot be parsed (error decoding domain name)");
+    BOOST_THROW_EXCEPTION(Error("SRV record cannot be parsed (error decoding domain name)"));
   }
 
   const srv_t* server = reinterpret_cast<const srv_t*>(&blob[sizeof(rechdr)]);
@@ -154,7 +154,7 @@
                                hostName,                      // expanded host name
                                NS_MAXDNAME);
   if (hostNameSize <= 0) {
-    throw Error("SRV record cannot be parsed (error decoding host name)");
+    BOOST_THROW_EXCEPTION(Error("SRV record cannot be parsed (error decoding host name)"));
   }
 
   std::string uri = "udp://";
diff --git a/tools/ndn-autoconfig/base.cpp b/tools/ndn-autoconfig/base.cpp
index bc14d9a..c896e67 100644
--- a/tools/ndn-autoconfig/base.cpp
+++ b/tools/ndn-autoconfig/base.cpp
@@ -65,7 +65,7 @@
 {
   std::ostringstream os;
   os << "FaceUri canonization failed: " << reason;
-  throw Error(os.str());
+  BOOST_THROW_EXCEPTION(Error(os.str()));
 }
 
 void
@@ -85,7 +85,7 @@
 {
   std::ostringstream os;
   os << "Failed to create face: " << error << " (code: " << code << ")";
-  throw Error(os.str());
+  BOOST_THROW_EXCEPTION(Error(os.str()));
 }
 
 void
@@ -113,7 +113,7 @@
 {
   std::ostringstream os;
   os << "Failed in name registration, " << error << " (code: " << code << ")";
-  throw Error(os.str());
+  BOOST_THROW_EXCEPTION(Error(os.str()));
 }
 
 
diff --git a/tools/ndn-autoconfig/main.cpp b/tools/ndn-autoconfig/main.cpp
index f7eb5db..2216535 100644
--- a/tools/ndn-autoconfig/main.cpp
+++ b/tools/ndn-autoconfig/main.cpp
@@ -72,7 +72,7 @@
                [&] (const std::string& errorMessage) {
                  std::cerr << "Stage 3 failed: " << errorMessage << std::endl;
                  if (!m_isDaemonMode)
-                   throw Error("No more stages, automatic discovery failed");
+                   BOOST_THROW_EXCEPTION(Error("No more stages, automatic discovery failed"));
                  else
                    std::cerr << "No more stages, automatic discovery failed" << std::endl;
                })
diff --git a/tools/nfdc.cpp b/tools/nfdc.cpp
index 0e5b8b9..4d65cf3 100644
--- a/tools/nfdc.cpp
+++ b/tools/nfdc.cpp
@@ -416,13 +416,13 @@
 void
 Nfdc::onCanonizeFailure(const std::string& reason)
 {
-  throw Error(reason);
+  BOOST_THROW_EXCEPTION(Error(reason));
 }
 
 void
 Nfdc::onObtainFaceIdFailure(const std::string& message)
 {
-  throw Error(message);
+  BOOST_THROW_EXCEPTION(Error(message));
 }
 
 void
@@ -430,7 +430,7 @@
 {
   boost::regex e("^[a-z0-9]+\\:.*");
   if (!boost::regex_match(m_commandLineArguments[0], e))
-    throw Error("invalid uri format");
+    BOOST_THROW_EXCEPTION(Error("invalid uri format"));
 
   ndn::util::FaceUri faceUri;
   faceUri.parse(m_commandLineArguments[0]);
@@ -517,7 +517,7 @@
 {
   std::ostringstream os;
   os << message << ": " << error << " (code: " << code << ")";
-  throw Error(os.str());
+  BOOST_THROW_EXCEPTION(Error(os.str()));
 }
 
 } // namespace nfdc