Replace all uses of BOOST_THROW_EXCEPTION with NDN_THROW

Refs: #4834
Change-Id: I1f9a614c83954873888d13c7b2b17a4fbff81058
diff --git a/docs/code-style.rst b/docs/code-style.rst
index dfad354..cc71192 100644
--- a/docs/code-style.rst
+++ b/docs/code-style.rst
@@ -669,9 +669,9 @@
 2.24. Exceptions can be suffixed with either ``Exception`` (e.g., ``SecurityException``) or
 ``Error`` (e.g., ``SecurityError``).
 
-    The recommended method is to declare exception class ``Exception`` or ``Error`` as an
-    inner class, from which the exception is thrown.  For example, when declaring class
-    ``Foo`` that can throw errors, one can write the following:
+    The recommended method is to declare an exception class ``Exception`` or ``Error`` as
+    a nested type inside the class from which the exception is thrown.  For example, when
+    defining a class ``Foo`` that can throw errors, one can write the following:
 
     .. code-block:: c++
 
@@ -686,7 +686,7 @@
             // You can inherit constructors from std::runtime_error like this:
             using std::runtime_error::runtime_error;
 
-            // Additional constructors, if desired, can be declared like this:
+            // Additional constructors, if desired, can be declared as usual:
             Error(const std::string& what, const std::exception& inner)
               : std::runtime_error(what + ": " + inner.what())
             {
@@ -1084,7 +1084,6 @@
         };
 
 3.31. The recommended way to throw an exception derived from ``std::exception`` is to use
-the ``BOOST_THROW_EXCEPTION``
-`macro <https://www.boost.org/doc/libs/1_58_0/libs/exception/doc/BOOST_THROW_EXCEPTION.html>`__.
-Exceptions thrown using this macro will be augmented with additional diagnostic information,
-including file name, line number, and function name from where the exception was thrown.
+``NDN_THROW`` or one of the other ``NDN_THROW_*`` macros.
+Exceptions thrown using these macros will be augmented with additional diagnostic information,
+including the file name, line number, and function name from which the exception was thrown.
diff --git a/ndn-cxx/data.cpp b/ndn-cxx/data.cpp
index e8e0841..abd4784 100644
--- a/ndn-cxx/data.cpp
+++ b/ndn-cxx/data.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -59,7 +59,7 @@
   // SignatureValue
   if (!wantUnsignedPortionOnly) {
     if (!m_signature) {
-      BOOST_THROW_EXCEPTION(Error("Requested wire format, but Data has not been signed"));
+      NDN_THROW(Error("Requested wire format, but Data has not been signed"));
     }
     totalLength += encoder.prependBlock(m_signature.getValue());
   }
@@ -133,7 +133,7 @@
 
   auto element = m_wire.elements_begin();
   if (element == m_wire.elements_end() || element->type() != tlv::Name) {
-    BOOST_THROW_EXCEPTION(Error("Name element is missing or out of order"));
+    NDN_THROW(Error("Name element is missing or out of order"));
   }
   m_name.wireDecode(*element);
   int lastElement = 1; // last recognized element index, in spec order
@@ -147,7 +147,7 @@
     switch (element->type()) {
       case tlv::MetaInfo: {
         if (lastElement >= 2) {
-          BOOST_THROW_EXCEPTION(Error("MetaInfo element is out of order"));
+          NDN_THROW(Error("MetaInfo element is out of order"));
         }
         m_metaInfo.wireDecode(*element);
         lastElement = 2;
@@ -155,7 +155,7 @@
       }
       case tlv::Content: {
         if (lastElement >= 3) {
-          BOOST_THROW_EXCEPTION(Error("Content element is out of order"));
+          NDN_THROW(Error("Content element is out of order"));
         }
         m_content = *element;
         lastElement = 3;
@@ -163,7 +163,7 @@
       }
       case tlv::SignatureInfo: {
         if (lastElement >= 4) {
-          BOOST_THROW_EXCEPTION(Error("SignatureInfo element is out of order"));
+          NDN_THROW(Error("SignatureInfo element is out of order"));
         }
         m_signature.setInfo(*element);
         lastElement = 4;
@@ -171,7 +171,7 @@
       }
       case tlv::SignatureValue: {
         if (lastElement >= 5) {
-          BOOST_THROW_EXCEPTION(Error("SignatureValue element is out of order"));
+          NDN_THROW(Error("SignatureValue element is out of order"));
         }
         m_signature.setValue(*element);
         lastElement = 5;
@@ -179,8 +179,7 @@
       }
       default: {
         if (tlv::isCriticalType(element->type())) {
-          BOOST_THROW_EXCEPTION(Error("unrecognized element of critical type " +
-                                      to_string(element->type())));
+          NDN_THROW(Error("unrecognized element of critical type " + to_string(element->type())));
         }
         break;
       }
@@ -188,7 +187,7 @@
   }
 
   if (!m_signature) {
-    BOOST_THROW_EXCEPTION(Error("SignatureInfo element is missing"));
+    NDN_THROW(Error("SignatureInfo element is missing"));
   }
 }
 
@@ -197,7 +196,7 @@
 {
   if (m_fullName.empty()) {
     if (!m_wire.hasWire()) {
-      BOOST_THROW_EXCEPTION(Error("Cannot compute full name because Data has no wire encoding (not signed)"));
+      NDN_THROW(Error("Cannot compute full name because Data has no wire encoding (not signed)"));
     }
     m_fullName = m_name;
     m_fullName.appendImplicitSha256Digest(util::Sha256::computeDigest(m_wire.wire(), m_wire.size()));
diff --git a/ndn-cxx/delegation-list.cpp b/ndn-cxx/delegation-list.cpp
index 33a9ad7..e2a5786 100644
--- a/ndn-cxx/delegation-list.cpp
+++ b/ndn-cxx/delegation-list.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -27,11 +27,6 @@
 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<DelegationList>));
 BOOST_CONCEPT_ASSERT((WireDecodable<DelegationList>));
 
-DelegationList::Error::Error(const std::string& what, const std::exception& innerException)
-  : Error(what + ": "s + innerException.what())
-{
-}
-
 DelegationList::DelegationList()
   : m_isSorted(true)
 {
@@ -67,12 +62,12 @@
 DelegationList::wireEncode(EncodingImpl<TAG>& encoder, uint32_t type) const
 {
   if (!isValidTlvType(type)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid TLV-TYPE " + to_string(type) +
-                                                " when encoding DelegationList"));
+    NDN_THROW(std::invalid_argument("Unexpected TLV-TYPE " + to_string(type) +
+                                    " while encoding DelegationList"));
   }
 
   if (this->size() == 0) {
-    BOOST_THROW_EXCEPTION(Error("Empty DelegationList"));
+    NDN_THROW(Error("Empty DelegationList"));
   }
 
   // LinkContent ::= (type) TLV-LENGTH
@@ -109,8 +104,7 @@
 DelegationList::wireDecode(const Block& block, bool wantSort)
 {
   if (!isValidTlvType(block.type())) {
-    BOOST_THROW_EXCEPTION(Error("Unexpected TLV-TYPE " + to_string(block.type()) +
-                                " when decoding DelegationList"));
+    NDN_THROW(Error("Unexpected TLV-TYPE " + to_string(block.type()) + " while decoding DelegationList"));
   }
 
   m_isSorted = wantSort;
@@ -119,40 +113,39 @@
   block.parse();
   for (const auto& del : block.elements()) {
     if (del.type() != tlv::LinkDelegation) {
-      BOOST_THROW_EXCEPTION(Error("Unexpected TLV-TYPE " + to_string(del.type()) +
-                                  " when decoding Delegation"));
+      NDN_THROW(Error("Unexpected TLV-TYPE " + to_string(del.type()) + " while decoding Delegation"));
     }
     del.parse();
 
     auto val = del.elements_begin();
     if (val == del.elements_end() || val->type() != tlv::LinkPreference) {
-      BOOST_THROW_EXCEPTION(Error("Missing Preference field in Delegation"));
+      NDN_THROW(Error("Missing Preference field in Delegation"));
     }
     uint64_t preference = 0;
     try {
       preference = readNonNegativeInteger(*val);
     }
-    catch (const tlv::Error& inner) {
-      BOOST_THROW_EXCEPTION(Error("Invalid Preference field in Delegation", inner));
+    catch (const tlv::Error&) {
+      NDN_THROW_NESTED(Error("Invalid Preference field in Delegation"));
     }
 
     ++val;
     if (val == del.elements_end() || val->type() != tlv::Name) {
-      BOOST_THROW_EXCEPTION(Error("Missing Name field in Delegation"));
+      NDN_THROW(Error("Missing Name field in Delegation"));
     }
     Name name;
     try {
       name.wireDecode(*val);
     }
-    catch (const tlv::Error& inner) {
-      BOOST_THROW_EXCEPTION(Error("Invalid Name field in Delegation", inner));
+    catch (const tlv::Error&) {
+      NDN_THROW_NESTED(Error("Invalid Name field in Delegation"));
     }
 
     this->insertImpl(preference, name);
   }
 
   if (this->size() == 0) {
-    BOOST_THROW_EXCEPTION(Error("Empty DelegationList"));
+    NDN_THROW(Error("Empty DelegationList"));
   }
 }
 
diff --git a/ndn-cxx/delegation-list.hpp b/ndn-cxx/delegation-list.hpp
index b4c4ad3..031072f 100644
--- a/ndn-cxx/delegation-list.hpp
+++ b/ndn-cxx/delegation-list.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -41,8 +41,6 @@
   {
   public:
     using tlv::Error::Error;
-
-    Error(const std::string& what, const std::exception& innerException);
   };
 
   /** \brief construct an empty DelegationList
diff --git a/ndn-cxx/detail/cf-string-osx.cpp b/ndn-cxx/detail/cf-string-osx.cpp
index ea63fc7..5cceb33 100644
--- a/ndn-cxx/detail/cf-string-osx.cpp
+++ b/ndn-cxx/detail/cf-string-osx.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -30,7 +30,7 @@
 {
   CFStringRef cfStr = CFStringCreateWithBytes(kCFAllocatorDefault, buf, buflen, kCFStringEncodingUTF8, false);
   if (cfStr == nullptr) {
-    BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create CFString from buffer"));
+    NDN_THROW(std::runtime_error("Failed to create CFString from buffer"));
   }
   return cfStr;
 }
@@ -40,7 +40,7 @@
 {
   CFStringRef cfStr = CFStringCreateWithCString(kCFAllocatorDefault, str.data(), kCFStringEncodingUTF8);
   if (cfStr == nullptr) {
-    BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create CFString from std::string"));
+    NDN_THROW(std::runtime_error("Failed to create CFString from std::string"));
   }
   return cfStr;
 }
@@ -58,7 +58,7 @@
   std::string str(CFStringGetLength(cfStr) + 1, '\0');
   // copy the CFString into the std::string buffer
   if (!CFStringGetCString(cfStr, &str.front(), str.size(), kCFStringEncodingUTF8)) {
-    BOOST_THROW_EXCEPTION(std::runtime_error("CFString to std::string conversion failed"));
+    NDN_THROW(std::runtime_error("CFString to std::string conversion failed"));
   }
   // drop the null terminator, std::string doesn't need it
   str.pop_back();
diff --git a/ndn-cxx/detail/common.hpp b/ndn-cxx/detail/common.hpp
index f5c95e6..b63d709 100644
--- a/ndn-cxx/detail/common.hpp
+++ b/ndn-cxx/detail/common.hpp
@@ -113,12 +113,12 @@
 #include <boost/assert.hpp>
 #include <boost/concept_check.hpp>
 #include <boost/noncopyable.hpp>
-#include <boost/throw_exception.hpp>
 
 namespace ndn {
 using boost::noncopyable;
 } // namespace ndn
 
 #include "ndn-cxx/util/backports.hpp"
+#include "ndn-cxx/util/exception.hpp"
 
 #endif // NDN_DETAIL_COMMON_HPP
diff --git a/ndn-cxx/encoding/block-helpers.cpp b/ndn-cxx/encoding/block-helpers.cpp
index e5a501f..82d2ff8 100644
--- a/ndn-cxx/encoding/block-helpers.cpp
+++ b/ndn-cxx/encoding/block-helpers.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -156,7 +156,7 @@
 readDouble(const Block& block)
 {
   if (block.value_size() != 8) {
-    BOOST_THROW_EXCEPTION(tlv::Error("Invalid length for double (must be 8)"));
+    NDN_THROW(tlv::Error("Invalid length for double (must be 8)"));
   }
 
   uint64_t temp = 0;
diff --git a/ndn-cxx/encoding/block-helpers.hpp b/ndn-cxx/encoding/block-helpers.hpp
index a8de879..fd29186 100644
--- a/ndn-cxx/encoding/block-helpers.hpp
+++ b/ndn-cxx/encoding/block-helpers.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -73,8 +73,7 @@
 {
   uint64_t value = readNonNegativeInteger(block);
   if (value > std::numeric_limits<R>::max()) {
-    BOOST_THROW_EXCEPTION(tlv::Error("Value in TLV element of type " + to_string(block.type()) +
-                          " is too large"));
+    NDN_THROW(tlv::Error("Value in TLV element of type " + to_string(block.type()) + " is too large"));
   }
   return static_cast<R>(value);
 }
diff --git a/ndn-cxx/encoding/block.cpp b/ndn-cxx/encoding/block.cpp
index e584467..5e51baf 100644
--- a/ndn-cxx/encoding/block.cpp
+++ b/ndn-cxx/encoding/block.cpp
@@ -67,14 +67,14 @@
   , m_size(m_end - m_begin)
 {
   if (m_buffer->size() == 0) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("buffer is empty"));
+    NDN_THROW(std::invalid_argument("Buffer is empty"));
   }
 
   const uint8_t* bufferBegin = &m_buffer->front();
   const uint8_t* bufferEnd = bufferBegin + m_buffer->size();
   if (&*begin < bufferBegin || &*begin > bufferEnd ||
       &*end   < bufferBegin || &*end   > bufferEnd) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("begin/end iterators points out of the buffer"));
+    NDN_THROW(std::invalid_argument("Begin/end iterators point outside the buffer"));
   }
 
   m_type = tlv::readType(m_valueBegin, m_valueEnd);
@@ -82,7 +82,7 @@
   // m_valueBegin now points to TLV-VALUE
 
   if (verifyLength && length != static_cast<uint64_t>(m_valueEnd - m_valueBegin)) {
-    BOOST_THROW_EXCEPTION(Error("TLV-LENGTH doesn't match buffer size"));
+    NDN_THROW(Error("TLV-LENGTH does not match buffer size"));
   }
 }
 
@@ -116,7 +116,7 @@
 
   BOOST_ASSERT(pos <= end);
   if (length > static_cast<uint64_t>(end - pos)) {
-    BOOST_THROW_EXCEPTION(Error("Not enough bytes in the buffer to fully parse TLV"));
+    NDN_THROW(Error("Not enough bytes in the buffer to fully parse TLV"));
   }
 
   BOOST_ASSERT(pos > buf);
@@ -171,14 +171,14 @@
 
   size_t tlSize = tlv::sizeOfVarNumber(type) + tlv::sizeOfVarNumber(length);
   if (tlSize + length > MAX_SIZE_OF_BLOCK_FROM_STREAM) {
-    BOOST_THROW_EXCEPTION(Error("TLV-LENGTH from stream exceeds limit"));
+    NDN_THROW(Error("TLV-LENGTH from stream exceeds limit"));
   }
 
   EncodingBuffer eb(tlSize + length, length);
   uint8_t* valueBuf = eb.buf();
   is.read(reinterpret_cast<char*>(valueBuf), length);
   if (length != static_cast<uint64_t>(is.gcount())) {
-    BOOST_THROW_EXCEPTION(Error("Not enough bytes from stream to fully parse TLV"));
+    NDN_THROW(Error("Not enough bytes from stream to fully parse TLV"));
   }
 
   eb.prependVarNumber(length);
@@ -262,7 +262,7 @@
 Block::begin() const
 {
   if (!hasWire())
-    BOOST_THROW_EXCEPTION(Error("Underlying wire buffer is empty"));
+    NDN_THROW(Error("Underlying wire buffer is empty"));
 
   return m_begin;
 }
@@ -271,7 +271,7 @@
 Block::end() const
 {
   if (!hasWire())
-    BOOST_THROW_EXCEPTION(Error("Underlying wire buffer is empty"));
+    NDN_THROW(Error("Underlying wire buffer is empty"));
 
   return m_end;
 }
@@ -280,7 +280,7 @@
 Block::wire() const
 {
   if (!hasWire())
-    BOOST_THROW_EXCEPTION(Error("Underlying wire buffer is empty"));
+    NDN_THROW(Error("Underlying wire buffer is empty"));
 
   return &*m_begin;
 }
@@ -289,7 +289,7 @@
 Block::size() const
 {
   if (empty()) {
-    BOOST_THROW_EXCEPTION(Error("Block size cannot be determined (undefined block size)"));
+    NDN_THROW(Error("Block size cannot be determined (undefined block size)"));
   }
 
   return m_size;
@@ -313,7 +313,7 @@
 Block::blockFromValue() const
 {
   if (!hasValue())
-    BOOST_THROW_EXCEPTION(Error("Block has no TLV-VALUE"));
+    NDN_THROW(Error("Block has no TLV-VALUE"));
 
   return Block(*this, m_valueBegin, m_valueEnd, true);
 }
@@ -336,8 +336,8 @@
     uint64_t length = tlv::readVarNumber(pos, end);
     if (length > static_cast<uint64_t>(end - pos)) {
       m_elements.clear();
-      BOOST_THROW_EXCEPTION(Error("TLV-LENGTH of sub-element of type " + to_string(type) +
-                                  " exceeds TLV-VALUE boundary of parent block"));
+      NDN_THROW(Error("TLV-LENGTH of sub-element of type " + to_string(type) +
+                      " exceeds TLV-VALUE boundary of parent block"));
     }
     // pos now points to TLV-VALUE of sub element
 
@@ -417,8 +417,8 @@
     return *it;
   }
 
-  BOOST_THROW_EXCEPTION(Error("No sub-element of type " + to_string(type) +
-                              " is found in block of type " + to_string(m_type)));
+  NDN_THROW(Error("No sub-element of type " + to_string(type) +
+                  " found in block of type " + to_string(m_type)));
 }
 
 Block::element_const_iterator
@@ -527,7 +527,7 @@
     ss.end();
   }
   catch (const t::Error&) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("input has odd number of hexadecimal digits"));
+    NDN_THROW(std::invalid_argument("Input has odd number of hexadecimal digits"));
   }
 
   return Block(os.buf());
diff --git a/ndn-cxx/encoding/tlv.cpp b/ndn-cxx/encoding/tlv.cpp
index babaf3d..a9feab7 100644
--- a/ndn-cxx/encoding/tlv.cpp
+++ b/ndn-cxx/encoding/tlv.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -24,6 +24,11 @@
 namespace ndn {
 namespace tlv {
 
+Error::Error(const char* expectedType, uint32_t actualType)
+  : Error("Expecting "s + expectedType + " element, but TLV has type " + to_string(actualType))
+{
+}
+
 std::ostream&
 operator<<(std::ostream& os, SignatureTypeValue st)
 {
diff --git a/ndn-cxx/encoding/tlv.hpp b/ndn-cxx/encoding/tlv.hpp
index f1cb59d..1b665fc 100644
--- a/ndn-cxx/encoding/tlv.hpp
+++ b/ndn-cxx/encoding/tlv.hpp
@@ -53,6 +53,8 @@
 {
 public:
   using std::runtime_error::runtime_error;
+
+  Error(const char* expectedType, uint32_t actualType);
 };
 
 /** @brief TLV-TYPE numbers defined in NDN Packet Format v0.3
@@ -420,13 +422,13 @@
 readVarNumber(Iterator& begin, Iterator end)
 {
   if (begin == end) {
-    BOOST_THROW_EXCEPTION(Error("Empty buffer during TLV parsing"));
+    NDN_THROW(Error("Empty buffer during TLV parsing"));
   }
 
   uint64_t value = 0;
   bool isOk = readVarNumber(begin, end, value);
   if (!isOk) {
-    BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV parsing"));
+    NDN_THROW(Error("Insufficient data during TLV parsing"));
   }
 
   return value;
@@ -438,7 +440,7 @@
 {
   uint64_t type = readVarNumber(begin, end);
   if (type > std::numeric_limits<uint32_t>::max()) {
-    BOOST_THROW_EXCEPTION(Error("TLV-TYPE number exceeds allowed maximum"));
+    NDN_THROW(Error("TLV-TYPE number exceeds allowed maximum"));
   }
 
   return static_cast<uint32_t>(type);
@@ -484,14 +486,13 @@
 readNonNegativeInteger(size_t size, Iterator& begin, Iterator end)
 {
   if (size != 1 && size != 2 && size != 4 && size != 8) {
-    BOOST_THROW_EXCEPTION(Error("Invalid length for nonNegativeInteger "
-                                "(only 1, 2, 4, and 8 are allowed)"));
+    NDN_THROW(Error("Invalid length " + to_string(size) + " for nonNegativeInteger"));
   }
 
   uint64_t number = 0;
   bool isOk = detail::ReadNumber<Iterator>()(size, begin, end, number);
   if (!isOk) {
-    BOOST_THROW_EXCEPTION(Error("Insufficient data during TLV parsing"));
+    NDN_THROW(Error("Insufficient data during nonNegativeInteger parsing"));
   }
 
   return number;
diff --git a/ndn-cxx/exclude.cpp b/ndn-cxx/exclude.cpp
index a8a5cd4..3204850 100644
--- a/ndn-cxx/exclude.cpp
+++ b/ndn-cxx/exclude.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -122,7 +122,7 @@
 Exclude::wireEncode(EncodingImpl<TAG>& encoder) const
 {
   if (m_entries.empty()) {
-    BOOST_THROW_EXCEPTION(Error("cannot encode empty Exclude selector"));
+    NDN_THROW(Error("cannot encode empty Exclude selector"));
   }
 
   size_t totalLength = 0;
@@ -168,13 +168,13 @@
   clear();
 
   if (wire.type() != tlv::Exclude)
-    BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV type when decoding Exclude"));
+    NDN_THROW(tlv::Error("Unexpected TLV type when decoding Exclude"));
 
   m_wire = wire;
   m_wire.parse();
 
   if (m_wire.elements_size() == 0) {
-    BOOST_THROW_EXCEPTION(Error("Exclude element cannot be empty"));
+    NDN_THROW(Error("Exclude element cannot be empty"));
   }
 
   // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (GenericNameComponent (Any)?)+
@@ -192,10 +192,10 @@
       component = name::Component(*i);
     }
     catch (const name::Component::Error&) {
-      BOOST_THROW_EXCEPTION(Error("Incorrect format of Exclude filter"));
+      NDN_THROW_NESTED(Error("Incorrect format of Exclude filter"));
     }
     if (!component.isGeneric() && !component.isImplicitSha256Digest()) {
-      BOOST_THROW_EXCEPTION(Error("Excluded component must be generic or ImplicitSha256Digest"));
+      NDN_THROW(Error("Excluded component must be generic or ImplicitSha256Digest"));
     }
     ++i;
 
@@ -274,8 +274,8 @@
 Exclude::excludeRange(const ExcludeComponent& from, const name::Component& to)
 {
   if (!from.isNegInf && from.component >= to) {
-    BOOST_THROW_EXCEPTION(Error("Invalid exclude range [" + from.component.toUri() + ", " + to.toUri() + "] "
-                                "(for single name exclude use Exclude::excludeOne)"));
+    NDN_THROW(Error("Invalid exclude range [" + from.component.toUri() + ", " + to.toUri() + "] "
+                    "(for single name exclude use Exclude::excludeOne)"));
   }
 
   ExcludeMap::iterator newFrom = m_entries.lower_bound(from);
diff --git a/ndn-cxx/face.cpp b/ndn-cxx/face.cpp
index 58c2617..a134e8e 100644
--- a/ndn-cxx/face.cpp
+++ b/ndn-cxx/face.cpp
@@ -138,14 +138,14 @@
       return TcpTransport::create(transportUri);
     }
     else {
-      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\""));
+      NDN_THROW(ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\""));
     }
   }
-  catch (const Transport::Error& error) {
-    BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
+  catch (const Transport::Error&) {
+    NDN_THROW_NESTED(ConfigFile::Error("Failed to create transport"));
   }
-  catch (const FaceUri::Error& error) {
-    BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
+  catch (const FaceUri::Error&) {
+    NDN_THROW_NESTED(ConfigFile::Error("Failed to create transport"));
   }
 }
 
diff --git a/ndn-cxx/impl/face-impl.hpp b/ndn-cxx/impl/face-impl.hpp
index 14599ab..5b5c39e 100644
--- a/ndn-cxx/impl/face-impl.hpp
+++ b/ndn-cxx/impl/face-impl.hpp
@@ -416,7 +416,7 @@
     }
 
     if (wire.size() > MAX_NDN_PACKET_SIZE) {
-      BOOST_THROW_EXCEPTION(Face::OversizedPacketError(pktType, name, wire.size()));
+      NDN_THROW(Face::OversizedPacketError(pktType, name, wire.size()));
     }
 
     return wire;
diff --git a/ndn-cxx/impl/name-component-types.hpp b/ndn-cxx/impl/name-component-types.hpp
index aaa3606..63fa4f2 100644
--- a/ndn-cxx/impl/name-component-types.hpp
+++ b/ndn-cxx/impl/name-component-types.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -189,8 +189,7 @@
   check(const Component& comp) const final
   {
     if (!match(comp)) {
-      BOOST_THROW_EXCEPTION(Error(m_typeName + " TLV-LENGTH must be " +
-                                  to_string(util::Sha256::DIGEST_SIZE)));
+      NDN_THROW(Error(m_typeName + " TLV-LENGTH must be " + to_string(util::Sha256::DIGEST_SIZE)));
     }
   }
 
@@ -239,7 +238,7 @@
       value = fromHex(input);
     }
     catch (const StringHelperError&) {
-      BOOST_THROW_EXCEPTION(Error("Cannot convert to " + m_typeName + " (invalid hex encoding)"));
+      NDN_THROW(Error("Cannot convert to " + m_typeName + " (invalid hex encoding)"));
     }
     return Component(m_type, std::move(value));
   }
diff --git a/ndn-cxx/ims/in-memory-storage.cpp b/ndn-cxx/ims/in-memory-storage.cpp
index 31ec616..c0499a9 100644
--- a/ndn-cxx/ims/in-memory-storage.cpp
+++ b/ndn-cxx/ims/in-memory-storage.cpp
@@ -137,7 +137,7 @@
     ssize_t nAllowedFailures = size() - m_capacity;
     while (size() > m_capacity) {
       if (!evictItem() && --nAllowedFailures < 0) {
-        BOOST_THROW_EXCEPTION(Error());
+        NDN_THROW(Error());
       }
     }
   }
diff --git a/ndn-cxx/interest-filter.cpp b/ndn-cxx/interest-filter.cpp
index a24e2d2..173c4dd 100644
--- a/ndn-cxx/interest-filter.cpp
+++ b/ndn-cxx/interest-filter.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -48,8 +48,8 @@
 InterestFilter::operator const Name&() const
 {
   if (hasRegexFilter()) {
-    BOOST_THROW_EXCEPTION(Error("Please update InterestCallback to accept const InterestFilter&"
-                                " (non-trivial InterestFilter is being used)"));
+    NDN_THROW(Error("Please update InterestCallback to accept `const InterestFilter&'"
+                    " (non-trivial InterestFilter is being used)"));
   }
   return m_prefix;
 }
diff --git a/ndn-cxx/interest.cpp b/ndn-cxx/interest.cpp
index 1fb3f1f..cebc226 100644
--- a/ndn-cxx/interest.cpp
+++ b/ndn-cxx/interest.cpp
@@ -49,7 +49,7 @@
   , m_interestLifetime(lifetime)
 {
   if (lifetime < 0_ms) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("InterestLifetime must be >= 0"));
+    NDN_THROW(std::invalid_argument("InterestLifetime must be >= 0"));
   }
 
   if (!boost::logic::indeterminate(s_defaultCanBePrefix)) {
@@ -78,7 +78,7 @@
     }
 #ifdef NDN_CXX_HAVE_TESTS
     if (s_errorIfCanBePrefixUnset) {
-      BOOST_THROW_EXCEPTION(std::logic_error("Interest.CanBePrefix is unset"));
+      NDN_THROW(std::logic_error("Interest.CanBePrefix is unset"));
     }
 #endif // NDN_CXX_HAVE_TESTS
   }
@@ -220,7 +220,7 @@
   m_wire.parse();
 
   if (m_wire.type() != tlv::Interest) {
-    BOOST_THROW_EXCEPTION(Error("expecting Interest element, got " + to_string(m_wire.type())));
+    NDN_THROW(Error("Interest", m_wire.type()));
   }
 
   if (!decode02()) {
@@ -260,7 +260,7 @@
   if (element != m_wire.elements_end() && element->type() == tlv::Nonce) {
     uint32_t nonce = 0;
     if (element->value_size() != sizeof(nonce)) {
-      BOOST_THROW_EXCEPTION(Error("Nonce element is malformed"));
+      NDN_THROW(Error("Nonce element is malformed"));
     }
     std::memcpy(&nonce, element->value(), sizeof(nonce));
     m_nonce = nonce;
@@ -306,11 +306,11 @@
 
   auto element = m_wire.elements_begin();
   if (element == m_wire.elements_end() || element->type() != tlv::Name) {
-    BOOST_THROW_EXCEPTION(Error("Name element is missing or out of order"));
+    NDN_THROW(Error("Name element is missing or out of order"));
   }
   m_name.wireDecode(*element);
   if (m_name.empty()) {
-    BOOST_THROW_EXCEPTION(Error("Name has zero name components"));
+    NDN_THROW(Error("Name has zero name components"));
   }
   int lastElement = 1; // last recognized element index, in spec order
 
@@ -324,10 +324,10 @@
     switch (element->type()) {
       case tlv::CanBePrefix: {
         if (lastElement >= 2) {
-          BOOST_THROW_EXCEPTION(Error("CanBePrefix element is out of order"));
+          NDN_THROW(Error("CanBePrefix element is out of order"));
         }
         if (element->value_size() != 0) {
-          BOOST_THROW_EXCEPTION(Error("CanBePrefix element has non-zero TLV-LENGTH"));
+          NDN_THROW(Error("CanBePrefix element has non-zero TLV-LENGTH"));
         }
         m_selectors.setMaxSuffixComponents(-1);
         lastElement = 2;
@@ -335,10 +335,10 @@
       }
       case tlv::MustBeFresh: {
         if (lastElement >= 3) {
-          BOOST_THROW_EXCEPTION(Error("MustBeFresh element is out of order"));
+          NDN_THROW(Error("MustBeFresh element is out of order"));
         }
         if (element->value_size() != 0) {
-          BOOST_THROW_EXCEPTION(Error("MustBeFresh element has non-zero TLV-LENGTH"));
+          NDN_THROW(Error("MustBeFresh element has non-zero TLV-LENGTH"));
         }
         m_selectors.setMustBeFresh(true);
         lastElement = 3;
@@ -346,7 +346,7 @@
       }
       case tlv::ForwardingHint: {
         if (lastElement >= 4) {
-          BOOST_THROW_EXCEPTION(Error("ForwardingHint element is out of order"));
+          NDN_THROW(Error("ForwardingHint element is out of order"));
         }
         m_forwardingHint.wireDecode(*element);
         lastElement = 4;
@@ -354,11 +354,11 @@
       }
       case tlv::Nonce: {
         if (lastElement >= 5) {
-          BOOST_THROW_EXCEPTION(Error("Nonce element is out of order"));
+          NDN_THROW(Error("Nonce element is out of order"));
         }
         uint32_t nonce = 0;
         if (element->value_size() != sizeof(nonce)) {
-          BOOST_THROW_EXCEPTION(Error("Nonce element is malformed"));
+          NDN_THROW(Error("Nonce element is malformed"));
         }
         std::memcpy(&nonce, element->value(), sizeof(nonce));
         m_nonce = nonce;
@@ -367,7 +367,7 @@
       }
       case tlv::InterestLifetime: {
         if (lastElement >= 6) {
-          BOOST_THROW_EXCEPTION(Error("InterestLifetime element is out of order"));
+          NDN_THROW(Error("InterestLifetime element is out of order"));
         }
         m_interestLifetime = time::milliseconds(readNonNegativeInteger(*element));
         lastElement = 6;
@@ -378,7 +378,7 @@
           break; // HopLimit is non-critical, ignore out-of-order appearance
         }
         if (element->value_size() != 1) {
-          BOOST_THROW_EXCEPTION(Error("HopLimit element is malformed"));
+          NDN_THROW(Error("HopLimit element is malformed"));
         }
         // TLV-VALUE is ignored
         lastElement = 7;
@@ -394,8 +394,7 @@
       }
       default: {
         if (tlv::isCriticalType(element->type())) {
-          BOOST_THROW_EXCEPTION(Error("unrecognized element of critical type " +
-                                      to_string(element->type())));
+          NDN_THROW(Error("Unrecognized element of critical type " + to_string(element->type())));
         }
         break;
       }
@@ -567,7 +566,7 @@
 Interest::setInterestLifetime(time::milliseconds lifetime)
 {
   if (lifetime < 0_ms) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("InterestLifetime must be >= 0"));
+    NDN_THROW(std::invalid_argument("InterestLifetime must be >= 0"));
   }
   m_interestLifetime = lifetime;
   m_wire.reset();
diff --git a/ndn-cxx/key-locator.cpp b/ndn-cxx/key-locator.cpp
index 453511e..5fe3b95 100644
--- a/ndn-cxx/key-locator.cpp
+++ b/ndn-cxx/key-locator.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -66,7 +66,7 @@
     totalLength += encoder.prependBlock(m_keyDigest);
     break;
   default:
-    BOOST_THROW_EXCEPTION(Error("Unsupported KeyLocator type"));
+    NDN_THROW(Error("Unsupported KeyLocator type " + to_string(m_type)));
   }
 
   totalLength += encoder.prependVarNumber(totalLength);
@@ -96,7 +96,7 @@
 KeyLocator::wireDecode(const Block& wire)
 {
   if (wire.type() != tlv::KeyLocator)
-    BOOST_THROW_EXCEPTION(Error("Unexpected TLV type during KeyLocator decoding"));
+    NDN_THROW(Error("KeyLocator", wire.type()));
 
   m_wire = wire;
   m_wire.parse();
@@ -135,7 +135,7 @@
 KeyLocator::getName() const
 {
   if (m_type != KeyLocator_Name)
-    BOOST_THROW_EXCEPTION(Error("KeyLocator type is not Name"));
+    NDN_THROW(Error("KeyLocator type is not Name"));
 
   return m_name;
 }
@@ -153,7 +153,7 @@
 KeyLocator::getKeyDigest() const
 {
   if (m_type != KeyLocator_KeyDigest)
-    BOOST_THROW_EXCEPTION(Error("KeyLocator type is not KeyDigest"));
+    NDN_THROW(Error("KeyLocator type is not KeyDigest"));
 
   return m_keyDigest;
 }
@@ -162,7 +162,7 @@
 KeyLocator::setKeyDigest(const Block& keyDigest)
 {
   if (keyDigest.type() != tlv::KeyDigest)
-    BOOST_THROW_EXCEPTION(Error("expecting KeyDigest block"));
+    NDN_THROW(Error("KeyDigest", keyDigest.type()));
 
   this->clear();
   m_type = KeyLocator_KeyDigest;
diff --git a/ndn-cxx/link.cpp b/ndn-cxx/link.cpp
index c1e056e..ab5cb0d 100644
--- a/ndn-cxx/link.cpp
+++ b/ndn-cxx/link.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -69,7 +69,7 @@
   Data::wireDecode(wire);
 
   if (getContentType() != tlv::ContentType_Link) {
-    BOOST_THROW_EXCEPTION(Error("Expected ContentType Link"));
+    NDN_THROW(Error("Expecting ContentType Link, got " + to_string(getContentType())));
   }
 
   m_delList.wireDecode(getContent(), wantSort);
diff --git a/ndn-cxx/lp/cache-policy.cpp b/ndn-cxx/lp/cache-policy.cpp
index 20d9662..1bc1aa1 100644
--- a/ndn-cxx/lp/cache-policy.cpp
+++ b/ndn-cxx/lp/cache-policy.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -57,7 +57,7 @@
 CachePolicy::wireEncode(EncodingImpl<TAG>& encoder) const
 {
   if (m_policy == CachePolicyType::NONE) {
-    BOOST_THROW_EXCEPTION(Error("CachePolicyType must be set"));
+    NDN_THROW(Error("CachePolicyType must be set"));
   }
 
   size_t length = 0;
@@ -73,7 +73,7 @@
 CachePolicy::wireEncode() const
 {
   if (m_policy == CachePolicyType::NONE) {
-    BOOST_THROW_EXCEPTION(Error("CachePolicyType must be set"));
+    NDN_THROW(Error("CachePolicyType must be set"));
   }
 
   if (m_wire.hasWire()) {
@@ -95,21 +95,25 @@
 CachePolicy::wireDecode(const Block& wire)
 {
   if (wire.type() != tlv::CachePolicy) {
-    BOOST_THROW_EXCEPTION(Error("expecting CachePolicy block"));
+    NDN_THROW(Error("CachePolicy", wire.type()));
   }
 
   m_wire = wire;
   m_wire.parse();
 
-  Block::element_const_iterator it = m_wire.elements_begin();
-  if (it != m_wire.elements_end() && it->type() == tlv::CachePolicyType) {
+  auto it = m_wire.elements_begin();
+  if (it == m_wire.elements_end()) {
+    NDN_THROW(Error("Empty CachePolicy"));
+  }
+
+  if (it->type() == tlv::CachePolicyType) {
     m_policy = static_cast<CachePolicyType>(readNonNegativeInteger(*it));
     if (this->getPolicy() == CachePolicyType::NONE) {
-      BOOST_THROW_EXCEPTION(Error("unknown CachePolicyType"));
+      NDN_THROW(Error("Unknown CachePolicyType"));
     }
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("expecting CachePolicyType block"));
+    NDN_THROW(Error("CachePolicyType", it->type()));
   }
 }
 
diff --git a/ndn-cxx/lp/field-decl.hpp b/ndn-cxx/lp/field-decl.hpp
index 95d8246..627ae13 100644
--- a/ndn-cxx/lp/field-decl.hpp
+++ b/ndn-cxx/lp/field-decl.hpp
@@ -59,10 +59,9 @@
   decode(const Block& wire)
   {
     if (wire.value_size() != 0) {
-      BOOST_THROW_EXCEPTION(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
-                                            " must be empty"));
+      NDN_THROW(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
+                                " must be empty"));
     }
-
     return EmptyValue{};
   }
 };
@@ -84,8 +83,8 @@
   decode(const Block& wire)
   {
     if (wire.value_size() != sizeof(uint64_t)) {
-      BOOST_THROW_EXCEPTION(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
-                                            " should contain a 64-bit integer"));
+      NDN_THROW(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
+                                " must contain a 64-bit integer"));
     }
     uint64_t n = 0;
     std::memcpy(&n, wire.value(), sizeof(n));
@@ -100,10 +99,9 @@
   decode(const Block& wire)
   {
     if (wire.value_size() == 0) {
-      BOOST_THROW_EXCEPTION(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
-                                            " cannot be empty"));
+      NDN_THROW(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
+                                " cannot be empty"));
     }
-
     return std::make_pair(wire.value_begin(), wire.value_end());
   }
 };
@@ -195,7 +193,7 @@
   decode(const Block& wire)
   {
     if (wire.type() != TlvType::value) {
-      BOOST_THROW_EXCEPTION(ndn::tlv::Error("Unexpected TLV-TYPE " + to_string(wire.type())));
+      NDN_THROW(ndn::tlv::Error("Unexpected TLV-TYPE " + to_string(wire.type())));
     }
 
     return DecodeHelper<TlvType, DECODER_TAG>::decode(wire);
diff --git a/ndn-cxx/lp/nack-header.cpp b/ndn-cxx/lp/nack-header.cpp
index 9a123ff..b9f5ffb 100644
--- a/ndn-cxx/lp/nack-header.cpp
+++ b/ndn-cxx/lp/nack-header.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -104,7 +104,7 @@
 NackHeader::wireDecode(const Block& wire)
 {
   if (wire.type() != tlv::Nack) {
-    BOOST_THROW_EXCEPTION(ndn::tlv::Error("expecting Nack block"));
+    NDN_THROW(ndn::tlv::Error("Nack", wire.type()));
   }
 
   m_wire = wire;
@@ -118,7 +118,7 @@
       m_reason = static_cast<NackReason>(readNonNegativeInteger(*it));
     }
     else {
-      BOOST_THROW_EXCEPTION(ndn::tlv::Error("expecting NackReason block"));
+      NDN_THROW(ndn::tlv::Error("NackReason", it->type()));
     }
   }
 }
diff --git a/ndn-cxx/lp/packet.cpp b/ndn-cxx/lp/packet.cpp
index d3e2a1d..9b84892 100644
--- a/ndn-cxx/lp/packet.cpp
+++ b/ndn-cxx/lp/packet.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -139,7 +139,7 @@
   }
 
   if (wire.type() != tlv::LpPacket) {
-    BOOST_THROW_EXCEPTION(Error("unrecognized TLV-TYPE " + to_string(wire.type())));
+    NDN_THROW(Error("LpPacket", wire.type()));
   }
 
   wire.parse();
@@ -150,16 +150,16 @@
     FieldInfo info(element.type());
 
     if (!info.isRecognized && !info.canIgnore) {
-      BOOST_THROW_EXCEPTION(Error("unrecognized field " + to_string(element.type()) + " cannot be ignored"));
+      NDN_THROW(Error("unrecognized field " + to_string(element.type()) + " cannot be ignored"));
     }
 
     if (!isFirst) {
       if (info.tlvType == prev.tlvType && !info.isRepeatable) {
-        BOOST_THROW_EXCEPTION(Error("non-repeatable field " + to_string(element.type()) + " cannot be repeated"));
+        NDN_THROW(Error("non-repeatable field " + to_string(element.type()) + " cannot be repeated"));
       }
 
       else if (info.tlvType != prev.tlvType && !compareFieldSortOrder(prev, info)) {
-        BOOST_THROW_EXCEPTION(Error("fields are not in correct sort order"));
+        NDN_THROW(Error("fields are not in correct sort order"));
       }
     }
 
diff --git a/ndn-cxx/lp/packet.hpp b/ndn-cxx/lp/packet.hpp
index e515134..624a0a5 100644
--- a/ndn-cxx/lp/packet.hpp
+++ b/ndn-cxx/lp/packet.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -84,8 +84,7 @@
   count() const
   {
     return std::count_if(m_wire.elements_begin(), m_wire.elements_end(),
-                         [] (const Block& block) {
-                           return block.type() == FIELD::TlvType::value; });
+                         [] (const Block& block) { return block.type() == FIELD::TlvType::value; });
   }
 
   /**
@@ -106,7 +105,7 @@
       }
     }
 
-    BOOST_THROW_EXCEPTION(std::out_of_range("Index out of range"));
+    NDN_THROW(std::out_of_range("lp::Packet::get: index out of range"));
   }
 
   /**
@@ -142,14 +141,14 @@
 
   /**
    * \brief add a FIELD with value
-   * \throw std::length_error if field already exists and is not repeatable
+   * \throw std::invalid_argument if field already exists and is not repeatable
    */
   template<typename FIELD>
   Packet&
   add(const typename FIELD::ValueType& value)
   {
     if (!FIELD::IsRepeatable::value && has<FIELD>()) {
-      BOOST_THROW_EXCEPTION(std::length_error("Field cannot be repeated"));
+      NDN_THROW(std::invalid_argument("lp::Packet::add: field cannot be repeated"));
     }
 
     EncodingEstimator estimator;
@@ -184,7 +183,7 @@
       }
     }
 
-    BOOST_THROW_EXCEPTION(std::out_of_range("Index out of range"));
+    NDN_THROW(std::out_of_range("lp::Packet::remove: index out of range"));
   }
 
   /**
diff --git a/ndn-cxx/lp/prefix-announcement-header.cpp b/ndn-cxx/lp/prefix-announcement-header.cpp
index 5433099..8761be1 100644
--- a/ndn-cxx/lp/prefix-announcement-header.cpp
+++ b/ndn-cxx/lp/prefix-announcement-header.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -36,7 +36,7 @@
   : m_prefixAnn(std::move(prefixAnn))
 {
   if (m_prefixAnn->getData() == nullopt) {
-    BOOST_THROW_EXCEPTION(Error("PrefixAnnouncement does not contain Data"));
+    NDN_THROW(Error("PrefixAnnouncement does not contain Data"));
   }
 }
 
@@ -45,7 +45,7 @@
 PrefixAnnouncementHeader::wireEncode(EncodingImpl<TAG>& encoder) const
 {
   if (m_prefixAnn == nullopt) {
-    BOOST_THROW_EXCEPTION(Error("PrefixAnnouncementHeader does not contain a PrefixAnnouncement"));
+    NDN_THROW(Error("PrefixAnnouncementHeader does not contain a PrefixAnnouncement"));
   }
 
   size_t length = 0;
@@ -61,7 +61,7 @@
 PrefixAnnouncementHeader::wireDecode(const Block& wire)
 {
   if (wire.type() != tlv::PrefixAnnouncement) {
-    BOOST_THROW_EXCEPTION(Error("Unexpected TLV-TYPE " + to_string(wire.type())));
+    NDN_THROW(Error("PrefixAnnouncement", wire.type()));
   }
 
   wire.parse();
diff --git a/ndn-cxx/meta-info.cpp b/ndn-cxx/meta-info.cpp
index eca1f25..b53a58c 100644
--- a/ndn-cxx/meta-info.cpp
+++ b/ndn-cxx/meta-info.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -55,7 +55,7 @@
 MetaInfo::setFreshnessPeriod(time::milliseconds freshnessPeriod)
 {
   if (freshnessPeriod < time::milliseconds::zero()) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("FreshnessPeriod must be >= 0"));
+    NDN_THROW(std::invalid_argument("FreshnessPeriod must be >= 0"));
   }
   m_wire.reset();
   m_freshnessPeriod = freshnessPeriod;
@@ -81,7 +81,7 @@
 {
   for (const auto& block : info) {
     if (block.type() < 128 || block.type() > 252)
-      BOOST_THROW_EXCEPTION(Error("AppMetaInfo block has type outside the application range [128, 252]"));
+      NDN_THROW(Error("AppMetaInfo block has type outside the application range [128, 252]"));
   }
 
   m_wire.reset();
@@ -93,8 +93,7 @@
 MetaInfo::addAppMetaInfo(const Block& block)
 {
   if (!(128 <= block.type() && block.type() <= 252))
-    BOOST_THROW_EXCEPTION(Error("AppMetaInfo block has type outside the application range "
-                                "[128, 252]"));
+    NDN_THROW(Error("AppMetaInfo block has type outside the application range [128, 252]"));
 
   m_wire.reset();
   m_appMetaInfo.push_back(block);
diff --git a/ndn-cxx/metadata-object.cpp b/ndn-cxx/metadata-object.cpp
index 78ad7f4..43212b6 100644
--- a/ndn-cxx/metadata-object.cpp
+++ b/ndn-cxx/metadata-object.cpp
@@ -21,8 +21,6 @@
 
 #include "ndn-cxx/metadata-object.hpp"
 
-#include <boost/lexical_cast.hpp>
-
 namespace ndn {
 
 static_assert(std::is_base_of<tlv::Error, MetadataObject::Error>::value,
@@ -35,14 +33,11 @@
 MetadataObject::MetadataObject(const Data& data)
 {
   if (data.getContentType() != tlv::ContentType_Blob) {
-    BOOST_THROW_EXCEPTION(Error("Expected ContentType to be BLOB but " +
-                                boost::lexical_cast<std::string>(data.getContentType()) +
-                                " is provided"));
+    NDN_THROW(Error("Expecting ContentType Blob, got " + to_string(data.getContentType())));
   }
 
   if (!isValidName(data.getName())) {
-    BOOST_THROW_EXCEPTION(Error("Name " + data.getName().toUri() +
-                                " is not a valid MetadataObject name"));
+    NDN_THROW(Error("Name " + data.getName().toUri() + " is not a valid MetadataObject name"));
   }
 
   data.getContent().parse();
@@ -58,8 +53,8 @@
                          time::milliseconds freshnessPeriod) const
 {
   if (discoveryInterestName.empty() || discoveryInterestName[-1] != KEYWORD_METADATA_COMP) {
-    BOOST_THROW_EXCEPTION(Error("Name " + discoveryInterestName.toUri() +
-                                " is not a valid discovery Interest name"));
+    NDN_THROW(Error("Name " + discoveryInterestName.toUri() +
+                    " is not a valid discovery Interest name"));
   }
   discoveryInterestName.appendVersion(version);
   discoveryInterestName.appendSegment(0);
diff --git a/ndn-cxx/mgmt/control-response.cpp b/ndn-cxx/mgmt/control-response.cpp
index d969d81..d0abdaf 100644
--- a/ndn-cxx/mgmt/control-response.cpp
+++ b/ndn-cxx/mgmt/control-response.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -73,17 +73,17 @@
   m_wire.parse();
 
   if (m_wire.type() != tlv::nfd::ControlResponse)
-    BOOST_THROW_EXCEPTION(Error("expected ControlResponse, got " + to_string(m_wire.type()) + " element"));
+    NDN_THROW(Error("ControlResponse", m_wire.type()));
 
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
   if (val == m_wire.elements_end() || val->type() != tlv::nfd::StatusCode) {
-    BOOST_THROW_EXCEPTION(Error("missing StatusCode sub-element"));
+    NDN_THROW(Error("missing StatusCode sub-element"));
   }
   m_code = readNonNegativeIntegerAs<uint32_t>(*val);
   ++val;
 
   if (val == m_wire.elements_end() || val->type() != tlv::nfd::StatusText) {
-    BOOST_THROW_EXCEPTION(Error("missing StatusText sub-element"));
+    NDN_THROW(Error("missing StatusText sub-element"));
   }
   m_text = readString(*val);
   ++val;
@@ -91,7 +91,7 @@
   if (val != m_wire.elements_end())
     m_body = *val;
   else
-    m_body = Block();
+    m_body = {};
 }
 
 std::ostream&
diff --git a/ndn-cxx/mgmt/dispatcher.cpp b/ndn-cxx/mgmt/dispatcher.cpp
index 326c511..306c7f3 100644
--- a/ndn-cxx/mgmt/dispatcher.cpp
+++ b/ndn-cxx/mgmt/dispatcher.cpp
@@ -63,7 +63,7 @@
                                   return x.first.isPrefixOf(prefix) || prefix.isPrefixOf(x.first);
                                 });
   if (hasOverlap) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("top-level prefix overlaps"));
+    NDN_THROW(std::out_of_range("top-level prefix overlaps"));
   }
 
   TopPrefixEntry& topPrefixEntry = m_topLevelPrefixes[prefix];
@@ -72,7 +72,7 @@
     topPrefixEntry.registeredPrefix = m_face.registerPrefix(prefix,
       nullptr,
       [] (const Name&, const std::string& reason) {
-        BOOST_THROW_EXCEPTION(std::runtime_error("prefix registration failed: " + reason));
+        NDN_THROW(std::runtime_error("prefix registration failed: " + reason));
       },
       signingInfo);
   }
@@ -225,11 +225,11 @@
                              StatusDatasetHandler handle)
 {
   if (!m_topLevelPrefixes.empty()) {
-    BOOST_THROW_EXCEPTION(std::domain_error("one or more top-level prefix has been added"));
+    NDN_THROW(std::domain_error("one or more top-level prefix has been added"));
   }
 
   if (isOverlappedWithOthers(relPrefix)) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("status dataset name overlaps"));
+    NDN_THROW(std::out_of_range("status dataset name overlaps"));
   }
 
   AuthorizationAcceptedCallback accepted =
@@ -300,11 +300,11 @@
 Dispatcher::addNotificationStream(const PartialName& relPrefix)
 {
   if (!m_topLevelPrefixes.empty()) {
-    BOOST_THROW_EXCEPTION(std::domain_error("one or more top-level prefix has been added"));
+    NDN_THROW(std::domain_error("one or more top-level prefix has been added"));
   }
 
   if (isOverlappedWithOthers(relPrefix)) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("notification stream name overlaps"));
+    NDN_THROW(std::out_of_range("notification stream name overlaps"));
   }
 
   // register a handler for the subscriber of this notification stream
diff --git a/ndn-cxx/mgmt/dispatcher.hpp b/ndn-cxx/mgmt/dispatcher.hpp
index c008b59..308e89a 100644
--- a/ndn-cxx/mgmt/dispatcher.hpp
+++ b/ndn-cxx/mgmt/dispatcher.hpp
@@ -463,11 +463,11 @@
                               ControlCommandHandler handle)
 {
   if (!m_topLevelPrefixes.empty()) {
-    BOOST_THROW_EXCEPTION(std::domain_error("one or more top-level prefix has been added"));
+    NDN_THROW(std::domain_error("one or more top-level prefix has been added"));
   }
 
   if (isOverlappedWithOthers(relPrefix)) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("relPrefix overlaps with another relPrefix"));
+    NDN_THROW(std::out_of_range("relPrefix overlaps with another relPrefix"));
   }
 
   auto parser = [] (const name::Component& comp) -> shared_ptr<ControlParameters> {
diff --git a/ndn-cxx/mgmt/nfd/channel-status.cpp b/ndn-cxx/mgmt/nfd/channel-status.cpp
index 6a79926..32d69a1 100644
--- a/ndn-cxx/mgmt/nfd/channel-status.cpp
+++ b/ndn-cxx/mgmt/nfd/channel-status.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -69,18 +69,19 @@
 ChannelStatus::wireDecode(const Block& block)
 {
   if (block.type() != tlv::nfd::ChannelStatus) {
-    BOOST_THROW_EXCEPTION(Error("Expecting ChannelStatus block"));
+    NDN_THROW(Error("ChannelStatus", block.type()));
   }
+
   m_wire = block;
   m_wire.parse();
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::LocalUri) {
     m_localUri = readString(*val);
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("Missing required LocalUri field"));
+    NDN_THROW(Error("Missing required LocalUri field"));
   }
 }
 
diff --git a/ndn-cxx/mgmt/nfd/command-options.cpp b/ndn-cxx/mgmt/nfd/command-options.cpp
index f0418c6..beeac16 100644
--- a/ndn-cxx/mgmt/nfd/command-options.cpp
+++ b/ndn-cxx/mgmt/nfd/command-options.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -37,7 +37,7 @@
 CommandOptions::setTimeout(const time::milliseconds& timeout)
 {
   if (timeout <= time::milliseconds::zero()) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("Timeout must be positive"));
+    NDN_THROW(std::out_of_range("Timeout must be positive"));
   }
 
   m_timeout = timeout;
diff --git a/ndn-cxx/mgmt/nfd/control-command.cpp b/ndn-cxx/mgmt/nfd/control-command.cpp
index c71d46c..86ca500 100644
--- a/ndn-cxx/mgmt/nfd/control-command.cpp
+++ b/ndn-cxx/mgmt/nfd/control-command.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -81,17 +81,17 @@
     bool isPresent = presentFields[i];
     if (m_required[i]) {
       if (!isPresent) {
-        BOOST_THROW_EXCEPTION(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is required but missing"));
+        NDN_THROW(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is required but missing"));
       }
     }
     else if (isPresent && !m_optional[i]) {
-      BOOST_THROW_EXCEPTION(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is forbidden but present"));
+      NDN_THROW(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is forbidden but present"));
     }
   }
 
   if (m_optional[CONTROL_PARAMETER_FLAGS] && m_optional[CONTROL_PARAMETER_MASK]) {
     if (parameters.hasFlags() != parameters.hasMask()) {
-      BOOST_THROW_EXCEPTION(ArgumentError("Flags must be accompanied by Mask"));
+      NDN_THROW(ArgumentError("Flags must be accompanied by Mask"));
     }
   }
 }
@@ -133,7 +133,7 @@
   this->ControlCommand::validateResponse(parameters);
 
   if (parameters.getFaceId() == INVALID_FACE_ID) {
-    BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
+    NDN_THROW(ArgumentError("FaceId must be valid"));
   }
 }
 
@@ -169,7 +169,7 @@
   this->ControlCommand::validateResponse(parameters);
 
   if (parameters.getFaceId() == INVALID_FACE_ID) {
-    BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
+    NDN_THROW(ArgumentError("FaceId must be valid"));
   }
 }
 
@@ -187,7 +187,7 @@
   this->ControlCommand::validateRequest(parameters);
 
   if (parameters.getFaceId() == INVALID_FACE_ID) {
-    BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
+    NDN_THROW(ArgumentError("FaceId must be valid"));
   }
 }
 
@@ -227,7 +227,7 @@
   this->ControlCommand::validateResponse(parameters);
 
   if (parameters.getFaceId() == INVALID_FACE_ID) {
-    BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
+    NDN_THROW(ArgumentError("FaceId must be valid"));
   }
 }
 
@@ -256,7 +256,7 @@
   this->ControlCommand::validateResponse(parameters);
 
   if (parameters.getFaceId() == INVALID_FACE_ID) {
-    BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
+    NDN_THROW(ArgumentError("FaceId must be valid"));
   }
 }
 
@@ -290,7 +290,7 @@
   this->ControlCommand::validateRequest(parameters);
 
   if (parameters.hasCount() && parameters.getCount() == 0) {
-    BOOST_THROW_EXCEPTION(ArgumentError("Count must be positive"));
+    NDN_THROW(ArgumentError("Count must be positive"));
   }
 }
 
@@ -300,7 +300,7 @@
   this->ControlCommand::validateResponse(parameters);
 
   if (parameters.hasCapacity() && parameters.getCapacity() == 0) {
-    BOOST_THROW_EXCEPTION(ArgumentError("Capacity must be positive"));
+    NDN_THROW(ArgumentError("Capacity must be positive"));
   }
 }
 
@@ -327,7 +327,7 @@
   this->ControlCommand::validateRequest(parameters);
 
   if (parameters.getName().size() == 0) {
-    BOOST_THROW_EXCEPTION(ArgumentError("Name must not be ndn:/"));
+    NDN_THROW(ArgumentError("Name must not be ndn:/"));
   }
 }
 
@@ -379,7 +379,7 @@
   this->ControlCommand::validateResponse(parameters);
 
   if (parameters.getFaceId() == INVALID_FACE_ID) {
-    BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
+    NDN_THROW(ArgumentError("FaceId must be valid"));
   }
 }
 
@@ -413,7 +413,7 @@
   this->ControlCommand::validateResponse(parameters);
 
   if (parameters.getFaceId() == INVALID_FACE_ID) {
-    BOOST_THROW_EXCEPTION(ArgumentError("FaceId must be valid"));
+    NDN_THROW(ArgumentError("FaceId must be valid"));
   }
 }
 
diff --git a/ndn-cxx/mgmt/nfd/control-parameters.cpp b/ndn-cxx/mgmt/nfd/control-parameters.cpp
index 86ca846..6c8f091 100644
--- a/ndn-cxx/mgmt/nfd/control-parameters.cpp
+++ b/ndn-cxx/mgmt/nfd/control-parameters.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -130,8 +130,9 @@
 ControlParameters::wireDecode(const Block& block)
 {
   if (block.type() != tlv::nfd::ControlParameters) {
-    BOOST_THROW_EXCEPTION(Error("Expecting TLV-TYPE ControlParameters"));
+    NDN_THROW(Error("ControlParameters", block.type()));
   }
+
   m_wire = block;
   m_wire.parse();
   Block::element_const_iterator val;
@@ -201,7 +202,7 @@
   if (this->hasStrategy()) {
     val->parse();
     if (val->elements().empty()) {
-      BOOST_THROW_EXCEPTION(Error("Expecting Strategy/Name"));
+      NDN_THROW(Error("Expecting Strategy/Name"));
     }
     else {
       m_strategy.wireDecode(*val->elements_begin());
@@ -243,7 +244,7 @@
 ControlParameters::hasFlagBit(size_t bit) const
 {
   if (bit >= 64) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
+    NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
   }
 
   if (!hasMask()) {
@@ -257,7 +258,7 @@
 ControlParameters::getFlagBit(size_t bit) const
 {
   if (bit >= 64) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
+    NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
   }
 
   if (!hasFlags()) {
@@ -271,7 +272,7 @@
 ControlParameters::setFlagBit(size_t bit, bool value, bool wantMask/* = true*/)
 {
   if (bit >= 64) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
+    NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
   }
 
   uint64_t flags = hasFlags() ? getFlags() : 0;
@@ -296,7 +297,7 @@
 ControlParameters::unsetFlagBit(size_t bit)
 {
   if (bit >= 64) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
+    NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
   }
 
   uint64_t mask = hasMask() ? getMask() : 0;
diff --git a/ndn-cxx/mgmt/nfd/cs-info.cpp b/ndn-cxx/mgmt/nfd/cs-info.cpp
index 77cf819..9e6d29d 100644
--- a/ndn-cxx/mgmt/nfd/cs-info.cpp
+++ b/ndn-cxx/mgmt/nfd/cs-info.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -82,7 +82,7 @@
 CsInfo::wireDecode(const Block& block)
 {
   if (block.type() != tlv::nfd::CsInfo) {
-    BOOST_THROW_EXCEPTION(Error("expecting CsInfo block, got " + to_string(block.type())));
+    NDN_THROW(Error("CsInfo", block.type()));
   }
   m_wire = block;
   m_wire.parse();
@@ -93,7 +93,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Capacity field"));
+    NDN_THROW(Error("missing required Capacity field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::Flags) {
@@ -101,7 +101,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Flags field"));
+    NDN_THROW(Error("missing required Flags field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NCsEntries) {
@@ -109,7 +109,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NCsEntries field"));
+    NDN_THROW(Error("missing required NCsEntries field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NHits) {
@@ -117,7 +117,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NHits field"));
+    NDN_THROW(Error("missing required NHits field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NMisses) {
@@ -125,7 +125,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NMisses field"));
+    NDN_THROW(Error("missing required NMisses field"));
   }
 }
 
diff --git a/ndn-cxx/mgmt/nfd/face-event-notification.cpp b/ndn-cxx/mgmt/nfd/face-event-notification.cpp
index 5ca888c..09a7e05 100644
--- a/ndn-cxx/mgmt/nfd/face-event-notification.cpp
+++ b/ndn-cxx/mgmt/nfd/face-event-notification.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -83,18 +83,19 @@
 FaceEventNotification::wireDecode(const Block& block)
 {
   if (block.type() != tlv::nfd::FaceEventNotification) {
-    BOOST_THROW_EXCEPTION(Error("expecting FaceEventNotification block"));
+    NDN_THROW(Error("FaceEventNotification", block.type()));
   }
+
   m_wire = block;
   m_wire.parse();
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceEventKind) {
     m_kind = readNonNegativeIntegerAs<FaceEventKind>(*val);
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required FaceEventKind field"));
+    NDN_THROW(Error("missing required FaceEventKind field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceId) {
@@ -102,7 +103,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required FaceId field"));
+    NDN_THROW(Error("missing required FaceId field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::Uri) {
@@ -110,7 +111,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Uri field"));
+    NDN_THROW(Error("missing required Uri field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::LocalUri) {
@@ -118,7 +119,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required LocalUri field"));
+    NDN_THROW(Error("missing required LocalUri field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceScope) {
@@ -126,7 +127,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required FaceScope field"));
+    NDN_THROW(Error("missing required FaceScope field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::FacePersistency) {
@@ -134,7 +135,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required FacePersistency field"));
+    NDN_THROW(Error("missing required FacePersistency field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::LinkType) {
@@ -142,7 +143,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required LinkType field"));
+    NDN_THROW(Error("missing required LinkType field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::Flags) {
@@ -150,7 +151,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Flags field"));
+    NDN_THROW(Error("missing required Flags field"));
   }
 }
 
diff --git a/ndn-cxx/mgmt/nfd/face-query-filter.cpp b/ndn-cxx/mgmt/nfd/face-query-filter.cpp
index 2a77ade..a0f8e19 100644
--- a/ndn-cxx/mgmt/nfd/face-query-filter.cpp
+++ b/ndn-cxx/mgmt/nfd/face-query-filter.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -104,14 +104,15 @@
 void
 FaceQueryFilter::wireDecode(const Block& block)
 {
-  // all fields are optional
   if (block.type() != tlv::nfd::FaceQueryFilter) {
-    BOOST_THROW_EXCEPTION(Error("expecting FaceQueryFilter block"));
+    NDN_THROW(Error("FaceQueryFilter", block.type()));
   }
 
   m_wire = block;
   m_wire.parse();
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
+
+  // all fields are optional
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceId) {
     m_faceId = readNonNegativeInteger(*val);
diff --git a/ndn-cxx/mgmt/nfd/face-status.cpp b/ndn-cxx/mgmt/nfd/face-status.cpp
index a4acbab..8727b40 100644
--- a/ndn-cxx/mgmt/nfd/face-status.cpp
+++ b/ndn-cxx/mgmt/nfd/face-status.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -112,18 +112,19 @@
 FaceStatus::wireDecode(const Block& block)
 {
   if (block.type() != tlv::nfd::FaceStatus) {
-    BOOST_THROW_EXCEPTION(Error("expecting FaceStatus block"));
+    NDN_THROW(Error("FaceStatus", block.type()));
   }
+
   m_wire = block;
   m_wire.parse();
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceId) {
     m_faceId = readNonNegativeInteger(*val);
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required FaceId field"));
+    NDN_THROW(Error("missing required FaceId field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::Uri) {
@@ -131,7 +132,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Uri field"));
+    NDN_THROW(Error("missing required Uri field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::LocalUri) {
@@ -139,7 +140,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required LocalUri field"));
+    NDN_THROW(Error("missing required LocalUri field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::ExpirationPeriod) {
@@ -155,7 +156,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required FaceScope field"));
+    NDN_THROW(Error("missing required FaceScope field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::FacePersistency) {
@@ -163,7 +164,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required FacePersistency field"));
+    NDN_THROW(Error("missing required FacePersistency field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::LinkType) {
@@ -171,7 +172,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required LinkType field"));
+    NDN_THROW(Error("missing required LinkType field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::BaseCongestionMarkingInterval) {
@@ -203,7 +204,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NInInterests field"));
+    NDN_THROW(Error("missing required NInInterests field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInData) {
@@ -211,7 +212,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NInData field"));
+    NDN_THROW(Error("missing required NInData field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInNacks) {
@@ -219,7 +220,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NInNacks field"));
+    NDN_THROW(Error("missing required NInNacks field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutInterests) {
@@ -227,7 +228,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NOutInterests field"));
+    NDN_THROW(Error("missing required NOutInterests field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutData) {
@@ -235,7 +236,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NOutData field"));
+    NDN_THROW(Error("missing required NOutData field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutNacks) {
@@ -243,7 +244,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NOutNacks field"));
+    NDN_THROW(Error("missing required NOutNacks field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInBytes) {
@@ -251,7 +252,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NInBytes field"));
+    NDN_THROW(Error("missing required NInBytes field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutBytes) {
@@ -259,7 +260,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NOutBytes field"));
+    NDN_THROW(Error("missing required NOutBytes field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::Flags) {
@@ -267,7 +268,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Flags field"));
+    NDN_THROW(Error("missing required Flags field"));
   }
 }
 
diff --git a/ndn-cxx/mgmt/nfd/face-traits.hpp b/ndn-cxx/mgmt/nfd/face-traits.hpp
index be07d16..f685e71 100644
--- a/ndn-cxx/mgmt/nfd/face-traits.hpp
+++ b/ndn-cxx/mgmt/nfd/face-traits.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -145,7 +145,7 @@
   getFlagBit(size_t bit) const
   {
     if (bit >= 64) {
-      BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
+      NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
     }
     return m_flags & (1 << bit);
   }
@@ -154,7 +154,7 @@
   setFlagBit(size_t bit, bool value)
   {
     if (bit >= 64) {
-      BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
+      NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
     }
 
     m_wire.reset();
diff --git a/ndn-cxx/mgmt/nfd/fib-entry.cpp b/ndn-cxx/mgmt/nfd/fib-entry.cpp
index 8989603..94154e3 100644
--- a/ndn-cxx/mgmt/nfd/fib-entry.cpp
+++ b/ndn-cxx/mgmt/nfd/fib-entry.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -96,26 +96,27 @@
 NextHopRecord::wireDecode(const Block& block)
 {
   if (block.type() != tlv::nfd::NextHopRecord) {
-    BOOST_THROW_EXCEPTION(Error("expecting NextHopRecord, but Block has type " + to_string(block.type())));
+    NDN_THROW(Error("NextHopRecord", block.type()));
   }
+
   m_wire = block;
   m_wire.parse();
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val == m_wire.elements_end()) {
-    BOOST_THROW_EXCEPTION(Error("unexpected end of NextHopRecord"));
+    NDN_THROW(Error("unexpected end of NextHopRecord"));
   }
   else if (val->type() != tlv::nfd::FaceId) {
-    BOOST_THROW_EXCEPTION(Error("expecting FaceId, but Block has type " + to_string(val->type())));
+    NDN_THROW(Error("FaceId", val->type()));
   }
   m_faceId = readNonNegativeInteger(*val);
   ++val;
 
   if (val == m_wire.elements_end()) {
-    BOOST_THROW_EXCEPTION(Error("unexpected end of NextHopRecord"));
+    NDN_THROW(Error("unexpected end of NextHopRecord"));
   }
   else if (val->type() != tlv::nfd::Cost) {
-    BOOST_THROW_EXCEPTION(Error("expecting Cost, but Block has type " + to_string(val->type())));
+    NDN_THROW(Error("Cost", val->type()));
   }
   m_cost = readNonNegativeInteger(*val);
   ++val;
@@ -208,17 +209,18 @@
 FibEntry::wireDecode(const Block& block)
 {
   if (block.type() != tlv::nfd::FibEntry) {
-    BOOST_THROW_EXCEPTION(Error("expecting FibEntry, but Block has type " + to_string(block.type())));
+    NDN_THROW(Error("FibEntry", block.type()));
   }
+
   m_wire = block;
   m_wire.parse();
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val == m_wire.elements_end()) {
-    BOOST_THROW_EXCEPTION(Error("unexpected end of FibEntry"));
+    NDN_THROW(Error("unexpected end of FibEntry"));
   }
   else if (val->type() != tlv::Name) {
-    BOOST_THROW_EXCEPTION(Error("expecting Name, but Block has type " + to_string(val->type())));
+    NDN_THROW(Error("Name", val->type()));
   }
   m_prefix.wireDecode(*val);
   ++val;
@@ -226,7 +228,7 @@
   m_nextHopRecords.clear();
   for (; val != m_wire.elements_end(); ++val) {
     if (val->type() != tlv::nfd::NextHopRecord) {
-      BOOST_THROW_EXCEPTION(Error("expecting NextHopRecord, but Block has type " + to_string(val->type())));
+      NDN_THROW(Error("NextHopRecord", val->type()));
     }
     m_nextHopRecords.emplace_back(*val);
   }
diff --git a/ndn-cxx/mgmt/nfd/fib-entry.hpp b/ndn-cxx/mgmt/nfd/fib-entry.hpp
index 4a74de2..74dd611 100644
--- a/ndn-cxx/mgmt/nfd/fib-entry.hpp
+++ b/ndn-cxx/mgmt/nfd/fib-entry.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -104,11 +104,7 @@
   class Error : public tlv::Error
   {
   public:
-    explicit
-    Error(const std::string& what)
-      : tlv::Error(what)
-    {
-    }
+    using tlv::Error::Error;
   };
 
   FibEntry();
diff --git a/ndn-cxx/mgmt/nfd/forwarder-status.cpp b/ndn-cxx/mgmt/nfd/forwarder-status.cpp
index 067c5c5..fc00be1 100644
--- a/ndn-cxx/mgmt/nfd/forwarder-status.cpp
+++ b/ndn-cxx/mgmt/nfd/forwarder-status.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -104,18 +104,19 @@
 ForwarderStatus::wireDecode(const Block& block)
 {
   if (block.type() != tlv::Content) {
-    BOOST_THROW_EXCEPTION(Error("expecting Content block for Status payload"));
+    NDN_THROW(Error("Content", block.type()));
   }
+
   m_wire = block;
   m_wire.parse();
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NfdVersion) {
     m_nfdVersion = readString(*val);
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NfdVersion field"));
+    NDN_THROW(Error("missing required NfdVersion field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::StartTimestamp) {
@@ -123,7 +124,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required StartTimestamp field"));
+    NDN_THROW(Error("missing required StartTimestamp field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::CurrentTimestamp) {
@@ -131,7 +132,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required CurrentTimestamp field"));
+    NDN_THROW(Error("missing required CurrentTimestamp field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NNameTreeEntries) {
@@ -139,7 +140,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NNameTreeEntries field"));
+    NDN_THROW(Error("missing required NNameTreeEntries field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NFibEntries) {
@@ -147,7 +148,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NFibEntries field"));
+    NDN_THROW(Error("missing required NFibEntries field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NPitEntries) {
@@ -155,7 +156,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NPitEntries field"));
+    NDN_THROW(Error("missing required NPitEntries field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NMeasurementsEntries) {
@@ -163,7 +164,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NMeasurementsEntries field"));
+    NDN_THROW(Error("missing required NMeasurementsEntries field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NCsEntries) {
@@ -171,7 +172,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NCsEntries field"));
+    NDN_THROW(Error("missing required NCsEntries field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInInterests) {
@@ -179,7 +180,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NInInterests field"));
+    NDN_THROW(Error("missing required NInInterests field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInData) {
@@ -187,7 +188,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NInData field"));
+    NDN_THROW(Error("missing required NInData field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInNacks) {
@@ -195,7 +196,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NInNacks field"));
+    NDN_THROW(Error("missing required NInNacks field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutInterests) {
@@ -203,7 +204,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NOutInterests field"));
+    NDN_THROW(Error("missing required NOutInterests field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutData) {
@@ -211,7 +212,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NOutData field"));
+    NDN_THROW(Error("missing required NOutData field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutNacks) {
@@ -219,7 +220,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NOutNacks field"));
+    NDN_THROW(Error("missing required NOutNacks field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NSatisfiedInterests) {
@@ -227,7 +228,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NSatisfiedInterests field"));
+    NDN_THROW(Error("missing required NSatisfiedInterests field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::NUnsatisfiedInterests) {
@@ -235,7 +236,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required NUnsatisfiedInterests field"));
+    NDN_THROW(Error("missing required NUnsatisfiedInterests field"));
   }
 }
 
diff --git a/ndn-cxx/mgmt/nfd/rib-entry.cpp b/ndn-cxx/mgmt/nfd/rib-entry.cpp
index 9486b6b..f565acb 100644
--- a/ndn-cxx/mgmt/nfd/rib-entry.cpp
+++ b/ndn-cxx/mgmt/nfd/rib-entry.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -140,18 +140,19 @@
 Route::wireDecode(const Block& block)
 {
   if (block.type() != tlv::nfd::Route) {
-    BOOST_THROW_EXCEPTION(Error("expecting Route, but Block has type " + to_string(block.type())));
+    NDN_THROW(Error("Route", block.type()));
   }
+
   m_wire = block;
   m_wire.parse();
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceId) {
     m_faceId = readNonNegativeInteger(*val);
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required FaceId field"));
+    NDN_THROW(Error("missing required FaceId field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::Origin) {
@@ -159,7 +160,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Origin field"));
+    NDN_THROW(Error("missing required Origin field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::Cost) {
@@ -167,7 +168,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Cost field"));
+    NDN_THROW(Error("missing required Cost field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::Flags) {
@@ -175,7 +176,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Flags field"));
+    NDN_THROW(Error("missing required Flags field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::ExpirationPeriod) {
@@ -287,17 +288,18 @@
 RibEntry::wireDecode(const Block& block)
 {
   if (block.type() != tlv::nfd::RibEntry) {
-    BOOST_THROW_EXCEPTION(Error("expecting RibEntry, but Block has type " + to_string(block.type())));
+    NDN_THROW(Error("RibEntry", block.type()));
   }
+
   m_wire = block;
   m_wire.parse();
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val == m_wire.elements_end()) {
-    BOOST_THROW_EXCEPTION(Error("unexpected end of RibEntry"));
+    NDN_THROW(Error("unexpected end of RibEntry"));
   }
   else if (val->type() != tlv::Name) {
-    BOOST_THROW_EXCEPTION(Error("expecting Name, but Block has type " + to_string(val->type())));
+    NDN_THROW(Error("Name", val->type()));
   }
   m_prefix.wireDecode(*val);
   ++val;
@@ -305,7 +307,7 @@
   m_routes.clear();
   for (; val != m_wire.elements_end(); ++val) {
     if (val->type() != tlv::nfd::Route) {
-      BOOST_THROW_EXCEPTION(Error("expecting Route, but Block has type " + to_string(val->type())));
+      NDN_THROW(Error("Route", val->type()));
     }
     m_routes.emplace_back(*val);
   }
diff --git a/ndn-cxx/mgmt/nfd/rib-entry.hpp b/ndn-cxx/mgmt/nfd/rib-entry.hpp
index a17daa1..2745be6 100644
--- a/ndn-cxx/mgmt/nfd/rib-entry.hpp
+++ b/ndn-cxx/mgmt/nfd/rib-entry.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -156,11 +156,7 @@
   class Error : public tlv::Error
   {
   public:
-    explicit
-    Error(const std::string& what)
-      : tlv::Error(what)
-    {
-    }
+    using tlv::Error::Error;
   };
 
   RibEntry();
diff --git a/ndn-cxx/mgmt/nfd/status-dataset.cpp b/ndn-cxx/mgmt/nfd/status-dataset.cpp
index 4233181..3d2a3d3 100644
--- a/ndn-cxx/mgmt/nfd/status-dataset.cpp
+++ b/ndn-cxx/mgmt/nfd/status-dataset.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -67,7 +67,7 @@
     Block block;
     std::tie(isOk, block) = Block::fromBuffer(payload, offset);
     if (!isOk) {
-      BOOST_THROW_EXCEPTION(StatusDataset::ParseResultError("cannot decode Block"));
+      NDN_THROW(StatusDataset::ParseResultError("cannot decode Block"));
     }
 
     offset += block.size();
diff --git a/ndn-cxx/mgmt/nfd/strategy-choice.cpp b/ndn-cxx/mgmt/nfd/strategy-choice.cpp
index 1beb439..c2a7524 100644
--- a/ndn-cxx/mgmt/nfd/strategy-choice.cpp
+++ b/ndn-cxx/mgmt/nfd/strategy-choice.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -73,24 +73,25 @@
 StrategyChoice::wireDecode(const Block& block)
 {
   if (block.type() != tlv::nfd::StrategyChoice) {
-    BOOST_THROW_EXCEPTION(Error("expecting StrategyChoice block"));
+    NDN_THROW(Error("StrategyChoice", block.type()));
   }
+
   m_wire = block;
   m_wire.parse();
-  Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val != m_wire.elements_end() && val->type() == tlv::Name) {
     m_name.wireDecode(*val);
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Name field"));
+    NDN_THROW(Error("missing required Name field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == tlv::nfd::Strategy) {
     val->parse();
     if (val->elements().empty()) {
-      BOOST_THROW_EXCEPTION(Error("expecting Strategy/Name"));
+      NDN_THROW(Error("expecting Strategy/Name"));
     }
     else {
       m_strategy.wireDecode(*val->elements_begin());
@@ -98,7 +99,7 @@
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("missing required Strategy field"));
+    NDN_THROW(Error("missing required Strategy field"));
   }
 }
 
diff --git a/ndn-cxx/mgmt/status-dataset-context.cpp b/ndn-cxx/mgmt/status-dataset-context.cpp
index 2fe9356..0487061 100644
--- a/ndn-cxx/mgmt/status-dataset-context.cpp
+++ b/ndn-cxx/mgmt/status-dataset-context.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -36,11 +36,11 @@
 StatusDatasetContext::setPrefix(const Name& prefix)
 {
   if (!m_interest.getName().isPrefixOf(prefix)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("prefix does not start with Interest Name"));
+    NDN_THROW(std::invalid_argument("prefix does not start with Interest Name"));
   }
 
   if (m_state != State::INITIAL) {
-    BOOST_THROW_EXCEPTION(std::domain_error("state is not in INITIAL"));
+    NDN_THROW(std::domain_error("state is not in INITIAL"));
   }
 
   m_prefix = prefix;
@@ -69,7 +69,7 @@
 StatusDatasetContext::append(const Block& block)
 {
   if (m_state == State::FINALIZED) {
-    BOOST_THROW_EXCEPTION(std::domain_error("state is in FINALIZED"));
+    NDN_THROW(std::domain_error("state is in FINALIZED"));
   }
 
   m_state = State::RESPONDED;
@@ -95,11 +95,10 @@
 StatusDatasetContext::end()
 {
   if (m_state == State::FINALIZED) {
-    BOOST_THROW_EXCEPTION(std::domain_error("state is in FINALIZED"));
+    NDN_THROW(std::domain_error("state is in FINALIZED"));
   }
 
   m_state = State::FINALIZED;
-
   m_dataSender(Name(m_prefix).appendSegment(m_segmentNo),
                makeBinaryBlock(tlv::Content, m_buffer->buf(), m_buffer->size()),
                m_expiry, true);
@@ -109,7 +108,7 @@
 StatusDatasetContext::reject(const ControlResponse& resp /*= a ControlResponse with 400*/)
 {
   if (m_state != State::INITIAL) {
-    BOOST_THROW_EXCEPTION(std::domain_error("state is in REPONSED or FINALIZED"));
+    NDN_THROW(std::domain_error("state is in RESPONDED or FINALIZED"));
   }
 
   m_state = State::FINALIZED;
diff --git a/ndn-cxx/name-component.cpp b/ndn-cxx/name-component.cpp
index cbfe05d..beaf62f 100644
--- a/ndn-cxx/name-component.cpp
+++ b/ndn-cxx/name-component.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -44,7 +44,7 @@
 Component::ensureValid() const
 {
   if (type() < tlv::NameComponentMin || type() > tlv::NameComponentMax) {
-    BOOST_THROW_EXCEPTION(Error("TLV-TYPE " + to_string(type()) + " is not a valid NameComponent"));
+    NDN_THROW(Error("TLV-TYPE " + to_string(type()) + " is not a valid NameComponent"));
   }
   detail::getComponentTypeTable().get(type()).check(*this);
 }
@@ -91,7 +91,7 @@
   std::string value = oss.str();
   if (value.find_first_not_of('.') == std::string::npos) { // all periods
     if (value.size() < 3) {
-      BOOST_THROW_EXCEPTION(Component::Error("Illegal URI (name component cannot be . or ..)"));
+      NDN_THROW(Component::Error("Illegal URI (name component cannot be . or ..)"));
     }
     return Component(type, reinterpret_cast<const uint8_t*>(value.data()), value.size() - 3);
   }
@@ -117,7 +117,7 @@
   auto typePrefix = input.substr(0, equalPos);
   auto ct = detail::getComponentTypeTable().findByUriPrefix(typePrefix);
   if (ct == nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Incorrect TLV-TYPE '" + typePrefix + "' in NameComponent URI"));
+    NDN_THROW(Error("Incorrect TLV-TYPE '" + typePrefix + "' in NameComponent URI"));
   }
   return ct->parseAltUriValue(input.substr(equalPos + 1));
 }
@@ -189,7 +189,7 @@
 Component::toNumber() const
 {
   if (!isNumber())
-    BOOST_THROW_EXCEPTION(Error("Name component does not have nonNegativeInteger value"));
+    NDN_THROW(Error("Name component does not have nonNegativeInteger value"));
 
   return readNonNegativeInteger(*this);
 }
@@ -198,8 +198,8 @@
 Component::toNumberWithMarker(uint8_t marker) const
 {
   if (!isNumberWithMarker(marker))
-    BOOST_THROW_EXCEPTION(Error("Name component does not have the requested marker "
-                                "or the value is not a nonNegativeInteger"));
+    NDN_THROW(Error("Name component does not have the requested marker "
+                    "or the value is not a nonNegativeInteger"));
 
   Buffer::const_iterator valueBegin = value_begin() + 1;
   return tlv::readNonNegativeInteger(value_size() - 1, valueBegin, value_end());
diff --git a/ndn-cxx/name.cpp b/ndn-cxx/name.cpp
index da6755f..5ea12cf 100644
--- a/ndn-cxx/name.cpp
+++ b/ndn-cxx/name.cpp
@@ -158,7 +158,7 @@
 Name::wireDecode(const Block& wire)
 {
   if (wire.type() != tlv::Name)
-    BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV type when decoding Name"));
+    NDN_THROW(tlv::Error("Name", wire.type()));
 
   m_wire = wire;
   m_wire.parse();
@@ -183,7 +183,7 @@
   }
 
   if (i < 0 || static_cast<size_t>(i) >= size()) {
-    BOOST_THROW_EXCEPTION(Error("Requested component does not exist (out of bounds)"));
+    NDN_THROW(Error("Requested component does not exist (out of bounds)"));
   }
 
   return reinterpret_cast<const Component&>(m_wire.elements()[i]);
diff --git a/ndn-cxx/net/dns.cpp b/ndn-cxx/net/dns.cpp
index d398117..54d21e4 100644
--- a/ndn-cxx/net/dns.cpp
+++ b/ndn-cxx/net/dns.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -150,7 +150,7 @@
   auto it = resolver.syncResolve(Resolver::query(host, ""));
 
   if (it == Resolver::iterator()) {
-    BOOST_THROW_EXCEPTION(Error("No endpoints match the specified address selector"));
+    NDN_THROW(Error("No endpoints match the specified address selector"));
   }
 
   return it->endpoint().address();
diff --git a/ndn-cxx/net/face-uri.cpp b/ndn-cxx/net/face-uri.cpp
index c1bbe8b..65372dd 100644
--- a/ndn-cxx/net/face-uri.cpp
+++ b/ndn-cxx/net/face-uri.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California,
+ * Copyright (c) 2013-2019 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -50,7 +50,7 @@
 FaceUri::FaceUri(const std::string& uri)
 {
   if (!parse(uri)) {
-    BOOST_THROW_EXCEPTION(Error("Malformed URI: " + uri));
+    NDN_THROW(Error("Malformed URI: " + uri));
   }
 }
 
diff --git a/ndn-cxx/net/face-uri.hpp b/ndn-cxx/net/face-uri.hpp
index 650e7c7..d1fed76 100644
--- a/ndn-cxx/net/face-uri.hpp
+++ b/ndn-cxx/net/face-uri.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California,
+ * Copyright (c) 2013-2019 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -47,11 +47,7 @@
   class Error : public std::invalid_argument
   {
   public:
-    explicit
-    Error(const std::string& what)
-      : std::invalid_argument(what)
-    {
-    }
+    using std::invalid_argument::invalid_argument;
   };
 
   FaceUri();
diff --git a/ndn-cxx/net/impl/netlink-socket.cpp b/ndn-cxx/net/impl/netlink-socket.cpp
index 9f9d4ef..6c60e6b 100644
--- a/ndn-cxx/net/impl/netlink-socket.cpp
+++ b/ndn-cxx/net/impl/netlink-socket.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -26,7 +26,6 @@
 #include "ndn-cxx/util/logger.hpp"
 #include "ndn-cxx/util/time.hpp"
 
-#include <cerrno>
 #include <linux/genetlink.h>
 #include <sys/socket.h>
 
@@ -63,7 +62,7 @@
 {
   int fd = ::socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol);
   if (fd < 0) {
-    BOOST_THROW_EXCEPTION(Error("Cannot create netlink socket ("s + std::strerror(errno) + ")"));
+    NDN_THROW_ERRNO(Error("Cannot create netlink socket"));
   }
   m_sock->assign(fd);
 
@@ -77,25 +76,25 @@
   // enable control messages for received packets to get the destination group
   const int one = 1;
   if (::setsockopt(fd, SOL_NETLINK, NETLINK_PKTINFO, &one, sizeof(one)) < 0) {
-    BOOST_THROW_EXCEPTION(Error("Cannot enable NETLINK_PKTINFO ("s + std::strerror(errno) + ")"));
+    NDN_THROW_ERRNO(Error("Cannot enable NETLINK_PKTINFO"));
   }
 
   sockaddr_nl addr{};
   addr.nl_family = AF_NETLINK;
   if (::bind(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
-    BOOST_THROW_EXCEPTION(Error("Cannot bind netlink socket ("s + std::strerror(errno) + ")"));
+    NDN_THROW_ERRNO(Error("Cannot bind netlink socket"));
   }
 
   // find out what pid has been assigned to us
   socklen_t len = sizeof(addr);
   if (::getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &len) < 0) {
-    BOOST_THROW_EXCEPTION(Error("Cannot obtain netlink socket address ("s + std::strerror(errno) + ")"));
+    NDN_THROW_ERRNO(Error("Cannot obtain netlink socket address"));
   }
   if (len != sizeof(addr)) {
-    BOOST_THROW_EXCEPTION(Error("Wrong address length (" + to_string(len) + ")"));
+    NDN_THROW(Error("Wrong address length (" + to_string(len) + ")"));
   }
   if (addr.nl_family != AF_NETLINK) {
-    BOOST_THROW_EXCEPTION(Error("Wrong address family (" + to_string(addr.nl_family) + ")"));
+    NDN_THROW(Error("Wrong address family (" + to_string(addr.nl_family) + ")"));
   }
   m_pid = addr.nl_pid;
   NDN_LOG_TRACE("our pid is " << m_pid);
@@ -114,8 +113,7 @@
 {
   if (::setsockopt(m_sock->native_handle(), SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
                    &group, sizeof(group)) < 0) {
-    BOOST_THROW_EXCEPTION(Error("Cannot join netlink group " + to_string(group) +
-                                " (" + std::strerror(errno) + ")"));
+    NDN_THROW_ERRNO(Error("Cannot join netlink group " + to_string(group)));
   }
 }
 
@@ -166,7 +164,7 @@
       }
       else if (ec) {
         NDN_LOG_ERROR("read failed: " << ec.message());
-        BOOST_THROW_EXCEPTION(Error("Netlink socket read error (" + ec.message() + ")"));
+        NDN_THROW(Error("Netlink socket read error (" + ec.message() + ")"));
       }
       else {
         receiveAndValidate();
@@ -194,21 +192,20 @@
 
   ssize_t nBytesRead = ::recvmsg(m_sock->native_handle(), &msg, 0);
   if (nBytesRead < 0) {
-    std::string errorString = std::strerror(errno);
     if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
       // not a fatal error
-      NDN_LOG_DEBUG("recvmsg failed: " << errorString);
+      NDN_LOG_DEBUG("recvmsg failed: " << std::strerror(errno));
       return;
     }
-    NDN_LOG_ERROR("recvmsg failed: " << errorString);
-    BOOST_THROW_EXCEPTION(Error("Netlink socket receive error (" + errorString + ")"));
+    NDN_LOG_ERROR("recvmsg failed: " << std::strerror(errno));
+    NDN_THROW_ERRNO(Error("Netlink socket receive error"));
   }
 
   NDN_LOG_TRACE("read " << nBytesRead << " bytes from netlink socket");
 
   if (msg.msg_flags & MSG_TRUNC) {
     NDN_LOG_ERROR("truncated message");
-    BOOST_THROW_EXCEPTION(Error("Received truncated netlink message"));
+    NDN_THROW(Error("Received truncated netlink message"));
     // TODO: grow the buffer and start over
   }
 
@@ -256,7 +253,7 @@
     }
     else if (nlmsg->nlmsg_flags & NLM_F_DUMP_INTR) {
       NDN_LOG_ERROR("dump is inconsistent");
-      BOOST_THROW_EXCEPTION(Error("Inconsistency detected in netlink dump"));
+      NDN_THROW(Error("Inconsistency detected in netlink dump"));
       // TODO: discard the rest of the message and retry the dump
     }
     else {
@@ -322,7 +319,7 @@
       }
       else if (ec != boost::asio::error::operation_aborted) {
         NDN_LOG_ERROR("write failed: " << ec.message());
-        BOOST_THROW_EXCEPTION(Error("Failed to send netlink request (" + ec.message() + ")"));
+        NDN_THROW(Error("Failed to send netlink request (" + ec.message() + ")"));
       }
   });
 }
@@ -433,7 +430,7 @@
       }
       else if (ec != boost::asio::error::operation_aborted) {
         NDN_LOG_ERROR("write failed: " << ec.message());
-        BOOST_THROW_EXCEPTION(Error("Failed to send netlink request (" + ec.message() + ")"));
+        NDN_THROW(Error("Failed to send netlink request (" + ec.message() + ")"));
       }
   });
 }
@@ -443,7 +440,7 @@
   , m_family(std::move(familyName))
 {
   if (m_family.size() >= GENL_NAMSIZ) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("netlink family name '" + m_family + "' too long"));
+    NDN_THROW(std::invalid_argument("netlink family name '" + m_family + "' too long"));
   }
 
   NDN_LOG_TRACE("resolving netlink family " << m_family);
diff --git a/ndn-cxx/net/impl/network-monitor-impl-osx.cpp b/ndn-cxx/net/impl/network-monitor-impl-osx.cpp
index 99f606f..f0866b8 100644
--- a/ndn-cxx/net/impl/network-monitor-impl-osx.cpp
+++ b/ndn-cxx/net/impl/network-monitor-impl-osx.cpp
@@ -81,7 +81,7 @@
   IfAddrs()
   {
     if (::getifaddrs(&m_ifaList) < 0) {
-      BOOST_THROW_EXCEPTION(NetworkMonitorImplOsx::Error("getifaddrs() failed: "s + strerror(errno)));
+      NDN_THROW_ERRNO(NetworkMonitorImplOsx::Error("getifaddrs() failed"));
     }
   }
 
@@ -140,7 +140,7 @@
   CFArrayAppendValue(patterns, CFSTR("State:/Network/Interface/.*/IPv6"));
 
   if (!SCDynamicStoreSetNotificationKeys(m_scStore.get(), nullptr, patterns)) {
-    BOOST_THROW_EXCEPTION(Error("SCDynamicStoreSetNotificationKeys failed"));
+    NDN_THROW(Error("SCDynamicStoreSetNotificationKeys failed"));
   }
 
   io.post([this] { enumerateInterfaces(); });
diff --git a/ndn-cxx/net/network-monitor-stub.cpp b/ndn-cxx/net/network-monitor-stub.cpp
index 25f8563..5dcc185 100644
--- a/ndn-cxx/net/network-monitor-stub.cpp
+++ b/ndn-cxx/net/network-monitor-stub.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -71,7 +71,7 @@
     BOOST_ASSERT(netif != nullptr);
     bool isNew = m_interfaces.emplace(netif->getName(), netif).second;
     if (!isNew) {
-      BOOST_THROW_EXCEPTION(std::invalid_argument("duplicate ifname"));
+      NDN_THROW(std::invalid_argument("duplicate ifname"));
     }
     this->emitSignal(onInterfaceAdded, netif);
   }
diff --git a/ndn-cxx/prefix-announcement.cpp b/ndn-cxx/prefix-announcement.cpp
index 6381cf6..da65e93 100644
--- a/ndn-cxx/prefix-announcement.cpp
+++ b/ndn-cxx/prefix-announcement.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -22,8 +22,6 @@
 #include "ndn-cxx/prefix-announcement.hpp"
 #include "ndn-cxx/encoding/tlv-nfd.hpp"
 
-#include <boost/lexical_cast.hpp>
-
 namespace ndn {
 
 static const name::Component KEYWORD_PA_COMP = "20025041"_block;
@@ -34,14 +32,14 @@
   : m_data(std::move(data))
 {
   if (m_data->getContentType() != tlv::ContentType_PrefixAnn) {
-    BOOST_THROW_EXCEPTION(Error("Data is not a prefix announcement: ContentType is " +
-                                boost::lexical_cast<std::string>(m_data->getContentType())));
+    NDN_THROW(Error("Data is not a prefix announcement: ContentType is " +
+                    to_string(m_data->getContentType())));
   }
 
   const Name& dataName = m_data->getName();
   if (dataName.size() < 3 || dataName[-3] != KEYWORD_PA_COMP ||
       !dataName[-2].isVersion() || !dataName[-1].isSegment()) {
-    BOOST_THROW_EXCEPTION(Error("Data is not a prefix announcement: wrong name structure"));
+    NDN_THROW(Error("Data is not a prefix announcement: wrong name structure"));
   }
   m_announcedName = dataName.getPrefix(-3);
 
@@ -58,8 +56,7 @@
   for (const Block& element : payload.elements()) {
     if (element.type() != tlv::nfd::ExpirationPeriod && element.type() != tlv::ValidityPeriod &&
         tlv::isCriticalType(element.type())) {
-      BOOST_THROW_EXCEPTION(Error("unrecognized element of critical type " +
-                                  to_string(element.type())));
+      NDN_THROW(Error("unrecognized element of critical type " + to_string(element.type())));
     }
   }
 }
@@ -102,7 +99,7 @@
 PrefixAnnouncement::setExpiration(time::milliseconds expiration)
 {
   if (expiration < 0_ms) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("expiration period is negative"));
+    NDN_THROW(std::invalid_argument("expiration period is negative"));
   }
   m_data.reset();
   m_expiration = expiration;
diff --git a/ndn-cxx/security/digest-sha256.cpp b/ndn-cxx/security/digest-sha256.cpp
index 36f6ae5..6332d1b 100644
--- a/ndn-cxx/security/digest-sha256.cpp
+++ b/ndn-cxx/security/digest-sha256.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -32,7 +32,7 @@
   : Signature(signature)
 {
   if (getType() != tlv::DigestSha256)
-    BOOST_THROW_EXCEPTION(Error("Cannot construct DigestSha256 from SignatureType " + to_string(getType())));
+    NDN_THROW(Error("Cannot construct DigestSha256 from SignatureType " + to_string(getType())));
 }
 
 } // namespace ndn
diff --git a/ndn-cxx/security/impl/openssl-helper.cpp b/ndn-cxx/security/impl/openssl-helper.cpp
index da4df1e..104723c 100644
--- a/ndn-cxx/security/impl/openssl-helper.cpp
+++ b/ndn-cxx/security/impl/openssl-helper.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -77,7 +77,7 @@
 #endif
 {
   if (m_ctx == nullptr)
-    BOOST_THROW_EXCEPTION(std::runtime_error("EVP_MD_CTX creation failed"));
+    NDN_THROW(std::runtime_error("EVP_MD_CTX creation failed"));
 }
 
 EvpMdCtx::~EvpMdCtx()
@@ -93,14 +93,14 @@
   : m_ctx(EVP_PKEY_CTX_new(key, nullptr))
 {
   if (m_ctx == nullptr)
-    BOOST_THROW_EXCEPTION(std::runtime_error("EVP_PKEY_CTX creation failed"));
+    NDN_THROW(std::runtime_error("EVP_PKEY_CTX creation failed"));
 }
 
 EvpPkeyCtx::EvpPkeyCtx(int id)
   : m_ctx(EVP_PKEY_CTX_new_id(id, nullptr))
 {
   if (m_ctx == nullptr)
-    BOOST_THROW_EXCEPTION(std::runtime_error("EVP_PKEY_CTX creation failed"));
+    NDN_THROW(std::runtime_error("EVP_PKEY_CTX creation failed"));
 }
 
 EvpPkeyCtx::~EvpPkeyCtx()
@@ -112,7 +112,7 @@
   : m_bio(BIO_new(method))
 {
   if (m_bio == nullptr)
-    BOOST_THROW_EXCEPTION(std::runtime_error("BIO creation failed"));
+    NDN_THROW(std::runtime_error("BIO creation failed"));
 }
 
 Bio::~Bio()
diff --git a/ndn-cxx/security/key-params.cpp b/ndn-cxx/security/key-params.cpp
index ec5325a..9d12bc8 100644
--- a/ndn-cxx/security/key-params.cpp
+++ b/ndn-cxx/security/key-params.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -53,7 +53,7 @@
 RsaKeyParamsInfo::checkKeySize(uint32_t size)
 {
   if (size < MIN_RSA_KEY_SIZE)
-    BOOST_THROW_EXCEPTION(KeyParams::Error("Unsupported RSA key size " + to_string(size)));
+    NDN_THROW(KeyParams::Error("Unsupported RSA key size " + to_string(size)));
   return size;
 }
 
@@ -70,7 +70,7 @@
     if (EC_KEY_SIZES[i] == size)
       return size;
   }
-  BOOST_THROW_EXCEPTION(KeyParams::Error("Unsupported EC key size " + to_string(size)));
+  NDN_THROW(KeyParams::Error("Unsupported EC key size " + to_string(size)));
 }
 
 uint32_t
@@ -86,7 +86,7 @@
     if (AES_KEY_SIZES[i] == size)
       return size;
   }
-  BOOST_THROW_EXCEPTION(KeyParams::Error("Unsupported AES key size " + to_string(size)));
+  NDN_THROW(KeyParams::Error("Unsupported AES key size " + to_string(size)));
 }
 
 uint32_t
diff --git a/ndn-cxx/security/pib/certificate-container.cpp b/ndn-cxx/security/pib/certificate-container.cpp
index f275869..a2a6762 100644
--- a/ndn-cxx/security/pib/certificate-container.cpp
+++ b/ndn-cxx/security/pib/certificate-container.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -116,8 +116,8 @@
 CertificateContainer::add(const v2::Certificate& certificate)
 {
   if (m_keyName != certificate.getKeyName())
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Certificate name `" + certificate.getKeyName().toUri() + "` "
-                                                "does not match key name"));
+    NDN_THROW(std::invalid_argument("Certificate name `" + certificate.getKeyName().toUri() + "` "
+                                    "does not match key name"));
 
   const Name& certName = certificate.getName();
   m_certNames.insert(certName);
@@ -130,8 +130,8 @@
 {
   if (!v2::Certificate::isValidName(certName) ||
       v2::extractKeyNameFromCertName(certName) != m_keyName) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
-                                                "is invalid or does not match key name"));
+    NDN_THROW(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
+                                    "is invalid or does not match key name"));
   }
 
   m_certNames.erase(certName);
@@ -149,8 +149,8 @@
 
   if (!v2::Certificate::isValidName(certName) ||
       v2::extractKeyNameFromCertName(certName) != m_keyName) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
-                                                "is invalid or does not match key name"));
+    NDN_THROW(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
+                                    "is invalid or does not match key name"));
   }
 
   m_certs[certName] = m_pib->getCertificate(certName);
diff --git a/ndn-cxx/security/pib/identity.cpp b/ndn-cxx/security/pib/identity.cpp
index 54a5f12..c9bd82b 100644
--- a/ndn-cxx/security/pib/identity.cpp
+++ b/ndn-cxx/security/pib/identity.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -92,7 +92,7 @@
   auto impl = m_impl.lock();
 
   if (impl == nullptr)
-    BOOST_THROW_EXCEPTION(std::domain_error("Invalid Identity instance"));
+    NDN_THROW(std::domain_error("Invalid Identity instance"));
 
   return impl;
 }
diff --git a/ndn-cxx/security/pib/impl/identity-impl.cpp b/ndn-cxx/security/pib/impl/identity-impl.cpp
index e9267ac..dd77a1b 100644
--- a/ndn-cxx/security/pib/impl/identity-impl.cpp
+++ b/ndn-cxx/security/pib/impl/identity-impl.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -40,7 +40,7 @@
     m_pib->addIdentity(m_name);
   }
   else if (!m_pib->hasIdentity(m_name)) {
-    BOOST_THROW_EXCEPTION(Pib::Error("Identity " + m_name.toUri() + " does not exist"));
+    NDN_THROW(Pib::Error("Identity " + m_name.toUri() + " does not exist"));
   }
 }
 
diff --git a/ndn-cxx/security/pib/impl/key-impl.cpp b/ndn-cxx/security/pib/impl/key-impl.cpp
index c2c8c32..79c0300 100644
--- a/ndn-cxx/security/pib/impl/key-impl.cpp
+++ b/ndn-cxx/security/pib/impl/key-impl.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -44,7 +44,7 @@
     publicKey.loadPkcs8(key, keyLen);
   }
   catch (const transform::PublicKey::Error&) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid key bits"));
+    NDN_THROW_NESTED(std::invalid_argument("Invalid key bits"));
   }
   m_keyType = publicKey.getKeyType();
 
diff --git a/ndn-cxx/security/pib/key-container.cpp b/ndn-cxx/security/pib/key-container.cpp
index d28b8d2..ccf3ad0 100644
--- a/ndn-cxx/security/pib/key-container.cpp
+++ b/ndn-cxx/security/pib/key-container.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -116,8 +116,8 @@
 KeyContainer::add(const uint8_t* key, size_t keyLen, const Name& keyName)
 {
   if (m_identity != v2::extractIdentityFromKeyName(keyName)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Key name `" + keyName.toUri() + "` does not match identity "
-                                                "`" + m_identity.toUri() + "`"));
+    NDN_THROW(std::invalid_argument("Key name `" + keyName.toUri() + "` does not match identity "
+                                    "`" + m_identity.toUri() + "`"));
   }
 
   m_keyNames.insert(keyName);
@@ -130,8 +130,8 @@
 KeyContainer::remove(const Name& keyName)
 {
   if (m_identity != v2::extractIdentityFromKeyName(keyName)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Key name `" + keyName.toUri() + "` does not match identity "
-                                                "`" + m_identity.toUri() + "`"));
+    NDN_THROW(std::invalid_argument("Key name `" + keyName.toUri() + "` does not match identity "
+                                    "`" + m_identity.toUri() + "`"));
   }
 
   m_keyNames.erase(keyName);
@@ -143,8 +143,8 @@
 KeyContainer::get(const Name& keyName) const
 {
   if (m_identity != v2::extractIdentityFromKeyName(keyName)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Key name `" + keyName.toUri() + "` does not match identity "
-                                                "`" + m_identity.toUri() + "`"));
+    NDN_THROW(std::invalid_argument("Key name `" + keyName.toUri() + "` does not match identity "
+                                    "`" + m_identity.toUri() + "`"));
   }
 
   shared_ptr<detail::KeyImpl> key;
diff --git a/ndn-cxx/security/pib/key.cpp b/ndn-cxx/security/pib/key.cpp
index 1b21aee..293effa 100644
--- a/ndn-cxx/security/pib/key.cpp
+++ b/ndn-cxx/security/pib/key.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -111,7 +111,7 @@
   auto impl = m_impl.lock();
 
   if (impl == nullptr) {
-    BOOST_THROW_EXCEPTION(std::domain_error("Invalid key instance"));
+    NDN_THROW(std::domain_error("Invalid key instance"));
   }
 
   return impl;
@@ -160,14 +160,13 @@
 extractIdentityFromKeyName(const Name& keyName)
 {
   if (!isValidKeyName(keyName)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Key name `" + keyName.toUri() + "` "
-                                                "does not follow the naming conventions"));
+    NDN_THROW(std::invalid_argument("Key name `" + keyName.toUri() + "` "
+                                    "does not respect the naming conventions"));
   }
 
   return keyName.getPrefix(-Certificate::MIN_KEY_NAME_LENGTH); // trim everything after and including "KEY"
 }
 
 } // namespace v2
-
 } // namespace security
 } // namespace ndn
diff --git a/ndn-cxx/security/pib/pib-memory.cpp b/ndn-cxx/security/pib/pib-memory.cpp
index 94bd9f6..5e365cc 100644
--- a/ndn-cxx/security/pib/pib-memory.cpp
+++ b/ndn-cxx/security/pib/pib-memory.cpp
@@ -118,7 +118,7 @@
     return m_defaultIdentity;
   }
 
-  BOOST_THROW_EXCEPTION(Pib::Error("No default identity"));
+  NDN_THROW(Pib::Error("No default identity"));
 }
 
 bool
@@ -158,7 +158,7 @@
 PibMemory::getKeyBits(const Name& keyName) const
 {
   if (!hasKey(keyName)) {
-    BOOST_THROW_EXCEPTION(Pib::Error("Key `" + keyName.toUri() + "` not found"));
+    NDN_THROW(Pib::Error("Key `" + keyName.toUri() + "` not found"));
   }
 
   auto key = m_keys.find(keyName);
@@ -182,7 +182,7 @@
 PibMemory::setDefaultKeyOfIdentity(const Name& identity, const Name& keyName)
 {
   if (!hasKey(keyName)) {
-    BOOST_THROW_EXCEPTION(Pib::Error("Key `" + keyName.toUri() + "` not found"));
+    NDN_THROW(Pib::Error("Key `" + keyName.toUri() + "` not found"));
   }
 
   m_defaultKeys[identity] = keyName;
@@ -193,7 +193,7 @@
 {
   auto defaultKey = m_defaultKeys.find(identity);
   if (defaultKey == m_defaultKeys.end()) {
-    BOOST_THROW_EXCEPTION(Pib::Error("No default key for identity `" + identity.toUri() + "`"));
+    NDN_THROW(Pib::Error("No default key for identity `" + identity.toUri() + "`"));
   }
 
   return defaultKey->second;
@@ -234,7 +234,7 @@
 PibMemory::getCertificate(const Name& certName) const
 {
   if (!hasCertificate(certName)) {
-    BOOST_THROW_EXCEPTION(Pib::Error("Certificate `" + certName.toUri() +  "` does not exist"));
+    NDN_THROW(Pib::Error("Certificate `" + certName.toUri() +  "` does not exist"));
   }
 
   auto it = m_certs.find(certName);
@@ -257,7 +257,7 @@
 PibMemory::setDefaultCertificateOfKey(const Name& keyName, const Name& certName)
 {
   if (!hasCertificate(certName)) {
-    BOOST_THROW_EXCEPTION(Pib::Error("Certificate `" + certName.toUri() +  "` does not exist"));
+    NDN_THROW(Pib::Error("Certificate `" + certName.toUri() +  "` does not exist"));
   }
 
   m_defaultCerts[keyName] = certName;
@@ -268,7 +268,7 @@
 {
   auto it = m_defaultCerts.find(keyName);
   if (it == m_defaultCerts.end()) {
-    BOOST_THROW_EXCEPTION(Pib::Error("No default certificate for key `" + keyName.toUri() + "`"));
+    NDN_THROW(Pib::Error("No default certificate for key `" + keyName.toUri() + "`"));
   }
 
   auto certIt = m_certs.find(it->second);
diff --git a/ndn-cxx/security/pib/pib-sqlite3.cpp b/ndn-cxx/security/pib/pib-sqlite3.cpp
index ac6c552..e460c2e 100644
--- a/ndn-cxx/security/pib/pib-sqlite3.cpp
+++ b/ndn-cxx/security/pib/pib-sqlite3.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -82,7 +82,6 @@
     UPDATE identities SET is_default=0;
   END;
 
-
 CREATE TABLE IF NOT EXISTS
   keys(
     id                    INTEGER PRIMARY KEY,
@@ -222,18 +221,19 @@
                                );
 
   if (result != SQLITE_OK) {
-    BOOST_THROW_EXCEPTION(PibImpl::Error("PIB database cannot be opened/created in " + location));
+    NDN_THROW(PibImpl::Error("PIB database cannot be opened/created in " + dbDir.string()));
   }
 
   // enable foreign key
   sqlite3_exec(m_database, "PRAGMA foreign_keys=ON", nullptr, nullptr, nullptr);
 
   // initialize PIB tables
-  char* errorMessage = nullptr;
-  result = sqlite3_exec(m_database, INITIALIZATION.c_str(), nullptr, nullptr, &errorMessage);
-  if (result != SQLITE_OK && errorMessage != nullptr) {
-    sqlite3_free(errorMessage);
-    BOOST_THROW_EXCEPTION(PibImpl::Error("PIB DB cannot be initialized"));
+  char* errmsg = nullptr;
+  result = sqlite3_exec(m_database, INITIALIZATION.c_str(), nullptr, nullptr, &errmsg);
+  if (result != SQLITE_OK && errmsg != nullptr) {
+    std::string what = "PIB database cannot be initialized: "s + errmsg;
+    sqlite3_free(errmsg);
+    NDN_THROW(PibImpl::Error(what));
   }
 }
 
@@ -280,7 +280,7 @@
 {
   Sqlite3Statement statement(m_database, "SELECT id FROM identities WHERE identity=?");
   statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
-  return (statement.step() == SQLITE_ROW);
+  return statement.step() == SQLITE_ROW;
 }
 
 void
@@ -340,7 +340,7 @@
   if (statement.step() == SQLITE_ROW)
     return Name(statement.getBlock(0));
   else
-    BOOST_THROW_EXCEPTION(Pib::Error("No default identity"));
+    NDN_THROW(Pib::Error("No default identity"));
 }
 
 bool
@@ -405,7 +405,7 @@
   if (statement.step() == SQLITE_ROW)
     return Buffer(statement.getBlob(0), statement.getSize(0));
   else
-    BOOST_THROW_EXCEPTION(Pib::Error("Key `" + keyName.toUri() + "` does not exist"));
+    NDN_THROW(Pib::Error("Key `" + keyName.toUri() + "` does not exist"));
 }
 
 std::set<Name>
@@ -430,7 +430,7 @@
 PibSqlite3::setDefaultKeyOfIdentity(const Name& identity, const Name& keyName)
 {
   if (!hasKey(keyName)) {
-    BOOST_THROW_EXCEPTION(Pib::Error("Key `" + keyName.toUri() + "` does not exist"));
+    NDN_THROW(Pib::Error("Key `" + keyName.toUri() + "` does not exist"));
   }
 
   Sqlite3Statement statement(m_database, "UPDATE keys SET is_default=1 WHERE key_name=?");
@@ -442,7 +442,7 @@
 PibSqlite3::getDefaultKeyOfIdentity(const Name& identity) const
 {
   if (!hasIdentity(identity)) {
-    BOOST_THROW_EXCEPTION(Pib::Error("Identity `" + identity.toUri() + "` does not exist"));
+    NDN_THROW(Pib::Error("Identity `" + identity.toUri() + "` does not exist"));
   }
 
   Sqlite3Statement statement(m_database,
@@ -455,7 +455,7 @@
     return Name(statement.getBlock(0));
   }
   else
-    BOOST_THROW_EXCEPTION(Pib::Error("No default key for identity `" + identity.toUri() + "`"));
+    NDN_THROW(Pib::Error("No default key for identity `" + identity.toUri() + "`"));
 }
 
 bool
@@ -526,7 +526,7 @@
   if (statement.step() == SQLITE_ROW)
     return v2::Certificate(statement.getBlock(0));
   else
-    BOOST_THROW_EXCEPTION(Pib::Error("Certificate `" + certName.toUri() + "` does not exit"));
+    NDN_THROW(Pib::Error("Certificate `" + certName.toUri() + "` does not exit"));
 }
 
 std::set<Name>
@@ -550,7 +550,7 @@
 PibSqlite3::setDefaultCertificateOfKey(const Name& keyName, const Name& certName)
 {
   if (!hasCertificate(certName)) {
-    BOOST_THROW_EXCEPTION(Pib::Error("Certificate `" + certName.toUri() + "` does not exist"));
+    NDN_THROW(Pib::Error("Certificate `" + certName.toUri() + "` does not exist"));
   }
 
   Sqlite3Statement statement(m_database,
@@ -571,7 +571,7 @@
   if (statement.step() == SQLITE_ROW)
     return v2::Certificate(statement.getBlock(0));
   else
-    BOOST_THROW_EXCEPTION(Pib::Error("No default certificate for key `" + keyName.toUri() + "`"));
+    NDN_THROW(Pib::Error("No default certificate for key `" + keyName.toUri() + "`"));
 }
 
 bool
@@ -583,7 +583,7 @@
                              "WHERE certificates.is_default=1 AND keys.key_name=?");
   statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
 
-  return (statement.step() == SQLITE_ROW);
+  return statement.step() == SQLITE_ROW;
 }
 
 } // namespace pib
diff --git a/ndn-cxx/security/pib/pib.cpp b/ndn-cxx/security/pib/pib.cpp
index ebf4256..a67bda5 100644
--- a/ndn-cxx/security/pib/pib.cpp
+++ b/ndn-cxx/security/pib/pib.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -62,7 +62,7 @@
 {
   std::string tpmLocator = m_impl->getTpmLocator();
   if (tpmLocator.empty()) {
-    BOOST_THROW_EXCEPTION(Pib::Error("TPM info does not exist"));
+    NDN_THROW(Pib::Error("TPM info does not exist"));
   }
   return tpmLocator;
 }
diff --git a/ndn-cxx/security/safe-bag.cpp b/ndn-cxx/security/safe-bag.cpp
index b0d8abc..af7067c 100644
--- a/ndn-cxx/security/safe-bag.cpp
+++ b/ndn-cxx/security/safe-bag.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -87,40 +87,43 @@
   EncodingBuffer buffer(estimatedSize, 0);
   wireEncode(buffer);
 
-  this->m_wire = buffer.block();
+  m_wire = buffer.block();
   return m_wire;
 }
 
 void
 SafeBag::wireDecode(const Block& wire)
 {
-  if (wire.type() != tlv::security::SafeBag)
-    BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV type when decoding safebag"));
+  if (wire.type() != tlv::security::SafeBag) {
+    NDN_THROW(tlv::Error("SafeBag", wire.type()));
+  }
 
-  this->m_wire = wire;
+  m_wire = wire;
   m_wire.parse();
-
-  Block::element_const_iterator it = m_wire.elements_begin();
+  auto it = m_wire.elements_begin();
 
   // Certificate must be the first part
   if (it != m_wire.elements_end()) {
-    this->m_certificate.wireDecode(*it);
+    m_certificate.wireDecode(*it);
     it++;
   }
-  else
-    BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV structure when decoding certificate"));
+  else {
+    NDN_THROW(tlv::Error("Unexpected TLV structure when decoding Certificate"));
+  }
 
   // EncryptedKeyBag
   if (it != m_wire.elements_end() && it->type() == tlv::security::EncryptedKeyBag) {
-    this->m_encryptedKeyBag = Buffer(it->value(), it->value_size());
+    m_encryptedKeyBag = Buffer(it->value(), it->value_size());
     it++;
   }
-  else
-    BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV structure when decoding encryptedkeybag"));
+  else {
+    NDN_THROW(tlv::Error("Unexpected TLV structure when decoding EncryptedKeyBag"));
+  }
 
   // Check if end
-  if (it != m_wire.elements_end())
-    BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV structure after decoding the block"));
+  if (it != m_wire.elements_end()) {
+    NDN_THROW(tlv::Error("Unexpected TLV element at the end of SafeBag"));
+  }
 }
 
 } // namespace security
diff --git a/ndn-cxx/security/signature-sha256-with-ecdsa.cpp b/ndn-cxx/security/signature-sha256-with-ecdsa.cpp
index 2fc526a..4c92514 100644
--- a/ndn-cxx/security/signature-sha256-with-ecdsa.cpp
+++ b/ndn-cxx/security/signature-sha256-with-ecdsa.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -32,17 +32,17 @@
   : Signature(signature)
 {
   if (getType() != tlv::SignatureSha256WithEcdsa)
-    BOOST_THROW_EXCEPTION(Error("Cannot construct Sha256WithEcdsa from SignatureType " + to_string(getType())));
+    NDN_THROW(Error("Cannot construct Sha256WithEcdsa from SignatureType " + to_string(getType())));
 
   if (!hasKeyLocator()) {
-    BOOST_THROW_EXCEPTION(Error("KeyLocator is missing in Sha256WithEcdsa signature"));
+    NDN_THROW(Error("KeyLocator is missing in Sha256WithEcdsa signature"));
   }
 }
 
 void
 SignatureSha256WithEcdsa::unsetKeyLocator()
 {
-  BOOST_THROW_EXCEPTION(Error("KeyLocator cannot be unset in Sha256WithEcdsa signature"));
+  NDN_THROW(Error("KeyLocator cannot be unset in Sha256WithEcdsa signature"));
 }
 
 } // namespace ndn
diff --git a/ndn-cxx/security/signature-sha256-with-rsa.cpp b/ndn-cxx/security/signature-sha256-with-rsa.cpp
index 9b2e678..5fd1aed 100644
--- a/ndn-cxx/security/signature-sha256-with-rsa.cpp
+++ b/ndn-cxx/security/signature-sha256-with-rsa.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -32,17 +32,17 @@
   : Signature(signature)
 {
   if (getType() != tlv::SignatureSha256WithRsa)
-    BOOST_THROW_EXCEPTION(Error("Cannot construct Sha256WithRsa from SignatureType " + to_string(getType())));
+    NDN_THROW(Error("Cannot construct Sha256WithRsa from SignatureType " + to_string(getType())));
 
   if (!hasKeyLocator()) {
-    BOOST_THROW_EXCEPTION(Error("KeyLocator is missing in Sha256WithRsa signature"));
+    NDN_THROW(Error("KeyLocator is missing in Sha256WithRsa signature"));
   }
 }
 
 void
 SignatureSha256WithRsa::unsetKeyLocator()
 {
-  BOOST_THROW_EXCEPTION(Error("KeyLocator cannot be unset in Sha256WithRsa signature"));
+  NDN_THROW(Error("KeyLocator cannot be unset in Sha256WithRsa signature"));
 }
 
 } // namespace ndn
diff --git a/ndn-cxx/security/signing-info.cpp b/ndn-cxx/security/signing-info.cpp
index ed760f0..848bdeb 100644
--- a/ndn-cxx/security/signing-info.cpp
+++ b/ndn-cxx/security/signing-info.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -81,7 +81,7 @@
 
   size_t pos = signingStr.find(':');
   if (pos == std::string::npos) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid signing string cannot represent SigningInfo"));
+    NDN_THROW(std::invalid_argument("Invalid signing string cannot represent SigningInfo"));
   }
 
   std::string scheme = signingStr.substr(0, pos);
@@ -102,7 +102,7 @@
     setSigningCertName(nameArg);
   }
   else {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid signing string scheme"));
+    NDN_THROW(std::invalid_argument("Invalid signing string scheme"));
   }
 }
 
@@ -181,7 +181,7 @@
       return os << "id:" << SigningInfo::getDigestSha256Identity();
   }
 
-  BOOST_THROW_EXCEPTION(std::invalid_argument("Unknown signer type"));
+  NDN_THROW(std::invalid_argument("Unknown signer type"));
   return os;
 }
 
diff --git a/ndn-cxx/security/tpm/back-end-file.cpp b/ndn-cxx/security/tpm/back-end-file.cpp
index 6f1af3b..22783ae 100644
--- a/ndn-cxx/security/tpm/back-end-file.cpp
+++ b/ndn-cxx/security/tpm/back-end-file.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -128,8 +128,8 @@
     saveKey(keyHandle->getKeyName(), *key);
     return keyHandle;
   }
-  catch (const std::runtime_error& e) {
-    BOOST_THROW_EXCEPTION(Error("Cannot write key to file: "s + e.what()));
+  catch (const std::runtime_error&) {
+    NDN_THROW_NESTED(Error("Cannot write key to file"));
   }
 }
 
@@ -143,8 +143,8 @@
   try {
     boost::filesystem::remove(keyPath);
   }
-  catch (const boost::filesystem::filesystem_error& e) {
-    BOOST_THROW_EXCEPTION(Error("Cannot remove key file: "s + e.what()));
+  catch (const boost::filesystem::filesystem_error&) {
+    NDN_THROW_NESTED(Error("Cannot remove key file"));
   }
 }
 
@@ -155,8 +155,8 @@
   try {
     key = loadKey(keyName);
   }
-  catch (const PrivateKey::Error& e) {
-    BOOST_THROW_EXCEPTION(Error("Cannot export private key: "s + e.what()));
+  catch (const PrivateKey::Error&) {
+    NDN_THROW_NESTED(Error("Cannot export private key"));
   }
 
   OBufferStream os;
@@ -172,8 +172,8 @@
     key.loadPkcs8(buf, size, pw, pwLen);
     saveKey(keyName, key);
   }
-  catch (const PrivateKey::Error& e) {
-    BOOST_THROW_EXCEPTION(Error("Cannot import private key: "s + e.what()));
+  catch (const PrivateKey::Error&) {
+    NDN_THROW_NESTED(Error("Cannot import private key"));
   }
 }
 
diff --git a/ndn-cxx/security/tpm/back-end-mem.cpp b/ndn-cxx/security/tpm/back-end-mem.cpp
index c6ec080..68e49d9 100644
--- a/ndn-cxx/security/tpm/back-end-mem.cpp
+++ b/ndn-cxx/security/tpm/back-end-mem.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -101,8 +101,8 @@
     key->loadPkcs8(buf, size, pw, pwLen);
     m_impl->keys[keyName] = key;
   }
-  catch (const PrivateKey::Error& e) {
-    BOOST_THROW_EXCEPTION(Error("Cannot import private key: "s + e.what()));
+  catch (const PrivateKey::Error&) {
+    NDN_THROW_NESTED(Error("Cannot import private key"));
   }
 }
 
diff --git a/ndn-cxx/security/tpm/back-end-osx.cpp b/ndn-cxx/security/tpm/back-end-osx.cpp
index 92ff4b1..9e28aab 100644
--- a/ndn-cxx/security/tpm/back-end-osx.cpp
+++ b/ndn-cxx/security/tpm/back-end-osx.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -86,7 +86,7 @@
   case KeyType::EC:
     return kSecAttrKeyTypeECDSA;
   default:
-    BOOST_THROW_EXCEPTION(Tpm::Error("Unsupported key type"));
+    NDN_THROW(Tpm::Error("Unsupported key type"));
   }
 }
 
@@ -147,7 +147,7 @@
     return nullptr;
   }
   else {
-    BOOST_THROW_EXCEPTION(BackEnd::Error("Key lookup in keychain failed: " + getErrorMessage(res)));
+    NDN_THROW(BackEnd::Error("Key lookup in keychain failed: " + getErrorMessage(res)));
   }
 }
 
@@ -174,7 +174,7 @@
                                &exportedKey.get());    // exportedData
 
   if (res != errSecSuccess) {
-    BOOST_THROW_EXCEPTION(BackEnd::Error("Failed to export private key: "s + getErrorMessage(res)));
+    NDN_THROW(BackEnd::Error("Failed to export private key: "s + getErrorMessage(res)));
   }
 
   outKey.loadPkcs8(CFDataGetBytePtr(exportedKey.get()), CFDataGetLength(exportedKey.get()),
@@ -188,7 +188,7 @@
 
   OSStatus res = SecKeychainCopyDefault(&m_impl->keyChainRef);
   if (res == errSecNoDefaultKeychain) {
-    BOOST_THROW_EXCEPTION(Error("No default keychain, create one first"));
+    NDN_THROW(Error("No default keychain, create one first"));
   }
 }
 
@@ -250,29 +250,26 @@
   CFReleaser<CFErrorRef> error;
   CFReleaser<SecTransformRef> signer = SecSignTransformCreate(key.get(), &error.get());
   if (signer == nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to create sign transform: " + getFailureReason(error.get())));
+    NDN_THROW(Error("Failed to create sign transform: " + getFailureReason(error.get())));
   }
 
   // Set input
   auto data = makeCFDataNoCopy(buf, size);
   SecTransformSetAttribute(signer.get(), kSecTransformInputAttributeName, data.get(), &error.get());
   if (error != nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to configure input of sign transform: " +
-                                getFailureReason(error.get())));
+    NDN_THROW(Error("Failed to configure input of sign transform: " + getFailureReason(error.get())));
   }
 
   // Enable use of padding
   SecTransformSetAttribute(signer.get(), kSecPaddingKey, kSecPaddingPKCS1Key, &error.get());
   if (error != nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to configure padding of sign transform: " +
-                                getFailureReason(error.get())));
+    NDN_THROW(Error("Failed to configure padding of sign transform: " + getFailureReason(error.get())));
   }
 
   // Set digest type
   SecTransformSetAttribute(signer.get(), kSecDigestTypeAttribute, getDigestAlgorithm(digestAlgo), &error.get());
   if (error != nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to configure digest type of sign transform: " +
-                                getFailureReason(error.get())));
+    NDN_THROW(Error("Failed to configure digest type of sign transform: " + getFailureReason(error.get())));
   }
 
   // Set digest length
@@ -280,15 +277,14 @@
   CFReleaser<CFNumberRef> cfDigestSize = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &digestSize);
   SecTransformSetAttribute(signer.get(), kSecDigestLengthAttribute, cfDigestSize.get(), &error.get());
   if (error != nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to configure digest length of sign transform: " +
-                                getFailureReason(error.get())));
+    NDN_THROW(Error("Failed to configure digest length of sign transform: " + getFailureReason(error.get())));
   }
 
   // Actually sign
   // C-style cast is used as per Apple convention
   CFReleaser<CFDataRef> signature = (CFDataRef)SecTransformExecute(signer.get(), &error.get());
   if (signature == nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to sign data: " + getFailureReason(error.get())));
+    NDN_THROW(Error("Failed to sign data: " + getFailureReason(error.get())));
   }
 
   return make_shared<Buffer>(CFDataGetBytePtr(signature.get()), CFDataGetLength(signature.get()));
@@ -300,26 +296,24 @@
   CFReleaser<CFErrorRef> error;
   CFReleaser<SecTransformRef> decryptor = SecDecryptTransformCreate(key.get(), &error.get());
   if (decryptor == nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to create decrypt transform: " + getFailureReason(error.get())));
+    NDN_THROW(Error("Failed to create decrypt transform: " + getFailureReason(error.get())));
   }
 
   auto data = makeCFDataNoCopy(cipherText, cipherSize);
   SecTransformSetAttribute(decryptor.get(), kSecTransformInputAttributeName, data.get(), &error.get());
   if (error != nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to configure input of decrypt transform: " +
-                                getFailureReason(error.get())));
+    NDN_THROW(Error("Failed to configure input of decrypt transform: " + getFailureReason(error.get())));
   }
 
   SecTransformSetAttribute(decryptor.get(), kSecPaddingKey, kSecPaddingOAEPKey, &error.get());
   if (error != nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to configure padding of decrypt transform: " +
-                                getFailureReason(error.get())));
+    NDN_THROW(Error("Failed to configure padding of decrypt transform: " + getFailureReason(error.get())));
   }
 
   // C-style cast is used as per Apple convention
   CFReleaser<CFDataRef> plainText = (CFDataRef)SecTransformExecute(decryptor.get(), &error.get());
   if (plainText == nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to decrypt data: " + getFailureReason(error.get())));
+    NDN_THROW(Error("Failed to decrypt data: " + getFailureReason(error.get())));
   }
 
   return make_shared<Buffer>(CFDataGetBytePtr(plainText.get()), CFDataGetLength(plainText.get()));
@@ -367,7 +361,7 @@
       break;
     }
     default: {
-      BOOST_THROW_EXCEPTION(Tpm::Error("Failed to generate key pair: Unsupported key type"));
+      NDN_THROW(Tpm::Error("Failed to generate key pair: Unsupported key type"));
     }
   }
   CFReleaser<CFNumberRef> cfKeySize = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keySize);
@@ -382,7 +376,7 @@
   privateKey.retain();
 
   if (res != errSecSuccess) {
-    BOOST_THROW_EXCEPTION(Error("Failed to generate key pair: " + getErrorMessage(res)));
+    NDN_THROW(Error("Failed to generate key pair: " + getErrorMessage(res)));
   }
 
   unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleOsx>(privateKey.get());
@@ -417,7 +411,7 @@
   OSStatus res = SecItemDelete(query.get());
 
   if (res != errSecSuccess && res != errSecItemNotFound) {
-    BOOST_THROW_EXCEPTION(Error("Failed to delete key pair: " + getErrorMessage(res)));
+    NDN_THROW(Error("Failed to delete key pair: " + getErrorMessage(res)));
   }
 }
 
@@ -426,7 +420,7 @@
 {
   KeyRefOsx keychainItem = getKeyRef(keyName);
   if (keychainItem == nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Failed to export private key: " + getErrorMessage(errSecItemNotFound)));
+    NDN_THROW(Error("Failed to export private key: " + getErrorMessage(errSecItemNotFound)));
   }
 
   transform::PrivateKey exportedKey;
@@ -435,8 +429,8 @@
     exportItem(keychainItem, exportedKey);
     exportedKey.savePkcs8(pkcs8, pw, pwLen);
   }
-  catch (const transform::PrivateKey::Error& e) {
-    BOOST_THROW_EXCEPTION(Error("Failed to export private key: "s + e.what()));
+  catch (const transform::PrivateKey::Error&) {
+    NDN_THROW_NESTED(Error("Failed to export private key"));
   }
   return pkcs8.buf();
 }
@@ -452,8 +446,8 @@
     privKey.loadPkcs8(buf, size, pw, pwLen);
     privKey.savePkcs1(pkcs1);
   }
-  catch (const transform::PrivateKey::Error& e) {
-    BOOST_THROW_EXCEPTION(Error("Failed to import private key: "s + e.what()));
+  catch (const transform::PrivateKey::Error&) {
+    NDN_THROW_NESTED(Error("Failed to import private key"));
   }
   auto keyToImport = makeCFDataNoCopy(pkcs1.buf()->data(), pkcs1.buf()->size());
 
@@ -468,7 +462,7 @@
                                  &access.get()); // accessRef
 
   if (res != errSecSuccess) {
-    BOOST_THROW_EXCEPTION(Error("Failed to import private key: " + getErrorMessage(res)));
+    NDN_THROW(Error("Failed to import private key: " + getErrorMessage(res)));
   }
 
   SecItemImportExportKeyParameters keyParams;
@@ -487,7 +481,7 @@
                       &outItems.get());    // outItems
 
   if (res != errSecSuccess) {
-    BOOST_THROW_EXCEPTION(Error("Failed to import private key: " + getErrorMessage(res)));
+    NDN_THROW(Error("Failed to import private key: " + getErrorMessage(res)));
   }
 
   // C-style cast is used as per Apple convention
diff --git a/ndn-cxx/security/tpm/back-end.cpp b/ndn-cxx/security/tpm/back-end.cpp
index 83ae426..8c54a1c 100644
--- a/ndn-cxx/security/tpm/back-end.cpp
+++ b/ndn-cxx/security/tpm/back-end.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -55,7 +55,7 @@
     case KeyIdType::USER_SPECIFIED: { // keyId is pre-set.
       Name keyName = v2::constructKeyName(identity, params.getKeyId());
       if (hasKey(keyName)) {
-        BOOST_THROW_EXCEPTION(Tpm::Error("Key `" + keyName.toUri() + "` already exists"));
+        NDN_THROW(Tpm::Error("Key `" + keyName.toUri() + "` already exists"));
       }
       break;
     }
@@ -75,7 +75,7 @@
       break;
     }
     default: {
-      BOOST_THROW_EXCEPTION(Error("Unsupported key id type"));
+      NDN_THROW(Error("Unsupported key id type"));
     }
   }
 
@@ -92,7 +92,7 @@
 BackEnd::exportKey(const Name& keyName, const char* pw, size_t pwLen)
 {
   if (!hasKey(keyName)) {
-    BOOST_THROW_EXCEPTION(Error("Key `" + keyName.toUri() + "` does not exist"));
+    NDN_THROW(Error("Key `" + keyName.toUri() + "` does not exist"));
   }
   return doExportKey(keyName, pw, pwLen);
 }
@@ -101,7 +101,7 @@
 BackEnd::importKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len, const char* pw, size_t pwLen)
 {
   if (hasKey(keyName)) {
-    BOOST_THROW_EXCEPTION(Error("Key `" + keyName.toUri() + "` already exists"));
+    NDN_THROW(Error("Key `" + keyName.toUri() + "` already exists"));
   }
   doImportKey(keyName, pkcs8, pkcs8Len, pw, pwLen);
 }
@@ -131,7 +131,7 @@
       break;
     }
     default: {
-      BOOST_THROW_EXCEPTION(Error("Unsupported key id type"));
+      NDN_THROW(Error("Unsupported key id type"));
     }
   }
 
diff --git a/ndn-cxx/security/tpm/key-handle-osx.cpp b/ndn-cxx/security/tpm/key-handle-osx.cpp
index 7172455..0421327 100644
--- a/ndn-cxx/security/tpm/key-handle-osx.cpp
+++ b/ndn-cxx/security/tpm/key-handle-osx.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -30,7 +30,7 @@
   : m_key(key)
 {
   if (m_key.get() == 0)
-    BOOST_THROW_EXCEPTION(Error("key is not set"));
+    NDN_THROW(Error("Key is not set"));
 }
 
 ConstBufferPtr
diff --git a/ndn-cxx/security/tpm/tpm.cpp b/ndn-cxx/security/tpm/tpm.cpp
index ecbf48f..87c1c84 100644
--- a/ndn-cxx/security/tpm/tpm.cpp
+++ b/ndn-cxx/security/tpm/tpm.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -23,6 +23,8 @@
 #include "ndn-cxx/security/tpm/back-end.hpp"
 #include "ndn-cxx/encoding/buffer-stream.hpp"
 
+#include <boost/lexical_cast.hpp>
+
 namespace ndn {
 namespace security {
 namespace tpm {
@@ -60,7 +62,8 @@
       return keyName;
     }
     default: {
-      BOOST_THROW_EXCEPTION(Error("Fail to create a key pair: Unsupported key type"));
+      NDN_THROW(Error("Failed to create key pair: Unsupported key type " +
+                      boost::lexical_cast<std::string>(params.getKeyType())));
     }
   }
 }
diff --git a/ndn-cxx/security/transform/base64-decode.cpp b/ndn-cxx/security/transform/base64-decode.cpp
index 7e47519..5b4de25 100644
--- a/ndn-cxx/security/transform/base64-decode.cpp
+++ b/ndn-cxx/security/transform/base64-decode.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -86,7 +86,7 @@
   if (wLen <= 0) { // fail to write data
     if (!BIO_should_retry(m_impl->m_source)) {
       // we haven't written everything but some error happens, and we cannot retry
-      BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
+      NDN_THROW(Error(getIndex(), "Failed to accept more input"));
     }
     return 0;
   }
diff --git a/ndn-cxx/security/transform/base64-encode.cpp b/ndn-cxx/security/transform/base64-encode.cpp
index 0400de2..f581300 100644
--- a/ndn-cxx/security/transform/base64-encode.cpp
+++ b/ndn-cxx/security/transform/base64-encode.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -77,7 +77,7 @@
   if (wLen <= 0) { // fail to write data
     if (!BIO_should_retry(m_impl->m_base64)) {
       // we haven't written everything but some error happens, and we cannot retry
-      BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
+      NDN_THROW(Error(getIndex(), "Failed to accept more input"));
     }
     return 0;
   }
@@ -91,7 +91,7 @@
 Base64Encode::finalize()
 {
   if (BIO_flush(m_impl->m_base64) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to flush"));
+    NDN_THROW(Error(getIndex(), "Failed to flush"));
 
   while (!isConverterEmpty()) {
     fillOutputBuffer();
diff --git a/ndn-cxx/security/transform/block-cipher.cpp b/ndn-cxx/security/transform/block-cipher.cpp
index a9bee3a..950099e 100644
--- a/ndn-cxx/security/transform/block-cipher.cpp
+++ b/ndn-cxx/security/transform/block-cipher.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -59,8 +59,8 @@
     initializeAesCbc(key, keyLen, iv, ivLen, op);
     break;
   default:
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported block cipher algorithm " +
-                                boost::lexical_cast<std::string>(algo)));
+    NDN_THROW(Error(getIndex(), "Unsupported block cipher algorithm " +
+                    boost::lexical_cast<std::string>(algo)));
   }
 }
 
@@ -83,7 +83,7 @@
   if (wLen <= 0) { // failed to write data
     if (!BIO_should_retry(m_impl->m_cipher)) {
       // we haven't written everything but some error happens, and we cannot retry
-      BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
+      NDN_THROW(Error(getIndex(), "Failed to accept more input"));
     }
     return 0;
   }
@@ -97,7 +97,7 @@
 BlockCipher::finalize()
 {
   if (BIO_flush(m_impl->m_cipher) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to flush"));
+    NDN_THROW(Error(getIndex(), "Failed to flush"));
 
   while (!isConverterEmpty()) {
     fillOutputBuffer();
@@ -146,12 +146,12 @@
     cipherType = EVP_aes_256_cbc();
     break;
   default:
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported key length " + to_string(keyLen)));
+    NDN_THROW(Error(getIndex(), "Unsupported key length " + to_string(keyLen)));
   }
 
   size_t requiredIvLen = static_cast<size_t>(EVP_CIPHER_iv_length(cipherType));
   if (ivLen != requiredIvLen)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "IV length must be " + to_string(requiredIvLen)));
+    NDN_THROW(Error(getIndex(), "IV length must be " + to_string(requiredIvLen)));
 
   BIO_set_cipher(m_impl->m_cipher, cipherType, key, iv, static_cast<int>(op));
 }
diff --git a/ndn-cxx/security/transform/digest-filter.cpp b/ndn-cxx/security/transform/digest-filter.cpp
index b0066b2..2293739 100644
--- a/ndn-cxx/security/transform/digest-filter.cpp
+++ b/ndn-cxx/security/transform/digest-filter.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -40,12 +40,10 @@
 {
   const EVP_MD* md = detail::digestAlgorithmToEvpMd(algo);
   if (md == nullptr)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported digest algorithm " +
-                                boost::lexical_cast<std::string>(algo)));
+    NDN_THROW(Error(getIndex(), "Unsupported digest algorithm " + boost::lexical_cast<std::string>(algo)));
 
   if (EVP_DigestInit_ex(m_impl->ctx, md, nullptr) == 0)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Cannot initialize digest " +
-                                boost::lexical_cast<std::string>(algo)));
+    NDN_THROW(Error(getIndex(), "Cannot initialize digest " + boost::lexical_cast<std::string>(algo)));
 }
 
 DigestFilter::~DigestFilter() = default;
@@ -54,7 +52,7 @@
 DigestFilter::convert(const uint8_t* buf, size_t size)
 {
   if (EVP_DigestUpdate(m_impl->ctx, buf, size) == 0)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
+    NDN_THROW(Error(getIndex(), "Failed to accept more input"));
 
   return size;
 }
@@ -66,7 +64,7 @@
   unsigned int mdLen = 0;
 
   if (EVP_DigestFinal_ex(m_impl->ctx, buffer->data(), &mdLen) == 0)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to finalize digest"));
+    NDN_THROW(Error(getIndex(), "Failed to finalize digest"));
 
   buffer->erase(buffer->begin() + mdLen, buffer->end());
   setOutputBuffer(std::move(buffer));
diff --git a/ndn-cxx/security/transform/hex-decode.cpp b/ndn-cxx/security/transform/hex-decode.cpp
index 0543319..9a91ee6 100644
--- a/ndn-cxx/security/transform/hex-decode.cpp
+++ b/ndn-cxx/security/transform/hex-decode.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -77,7 +77,7 @@
 HexDecode::finalize()
 {
   if (m_hasOddByte)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Incomplete input"));
+    NDN_THROW(Error(getIndex(), "Incomplete input"));
 }
 
 unique_ptr<Transform::OBuffer>
@@ -89,7 +89,7 @@
 
   if (m_hasOddByte) {
     if (C2H[hex[0]] < 0 || C2H[m_oddByte] < 0)
-      BOOST_THROW_EXCEPTION(Error(getIndex(), "Wrong input byte"));
+      NDN_THROW(Error(getIndex(), "Wrong input byte"));
 
     *it = (C2H[m_oddByte] << 4) + C2H[hex[0]];
     ++it;
@@ -99,7 +99,7 @@
 
   while (hexLen >= 2) {
     if (C2H[hex[0]] < 0 || C2H[hex[1]] < 0)
-      BOOST_THROW_EXCEPTION(Error(getIndex(), "Wrong input byte"));
+      NDN_THROW(Error(getIndex(), "Wrong input byte"));
 
     *it = (C2H[hex[0]] << 4) + C2H[hex[1]];
     ++it;
diff --git a/ndn-cxx/security/transform/hmac-filter.cpp b/ndn-cxx/security/transform/hmac-filter.cpp
index 4ab4a97..205b480 100644
--- a/ndn-cxx/security/transform/hmac-filter.cpp
+++ b/ndn-cxx/security/transform/hmac-filter.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -55,16 +55,15 @@
 
   const EVP_MD* md = detail::digestAlgorithmToEvpMd(algo);
   if (md == nullptr)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported digest algorithm " +
-                                boost::lexical_cast<std::string>(algo)));
+    NDN_THROW(Error(getIndex(), "Unsupported digest algorithm " + boost::lexical_cast<std::string>(algo)));
 
   m_impl->key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, key, static_cast<int>(keyLen));
   if (m_impl->key == nullptr)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to create HMAC key"));
+    NDN_THROW(Error(getIndex(), "Failed to create HMAC key"));
 
   if (EVP_DigestSignInit(m_impl->ctx, nullptr, md, nullptr, m_impl->key) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to initialize HMAC context with " +
-                                boost::lexical_cast<std::string>(algo) + " digest"));
+    NDN_THROW(Error(getIndex(), "Failed to initialize HMAC context with " +
+                    boost::lexical_cast<std::string>(algo) + " digest"));
 }
 
 HmacFilter::~HmacFilter() = default;
@@ -73,7 +72,7 @@
 HmacFilter::convert(const uint8_t* buf, size_t size)
 {
   if (EVP_DigestSignUpdate(m_impl->ctx, buf, size) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
+    NDN_THROW(Error(getIndex(), "Failed to accept more input"));
 
   return size;
 }
@@ -85,7 +84,7 @@
   size_t hmacLen = 0;
 
   if (EVP_DigestSignFinal(m_impl->ctx, buffer->data(), &hmacLen) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to finalize HMAC"));
+    NDN_THROW(Error(getIndex(), "Failed to finalize HMAC"));
 
   buffer->erase(buffer->begin() + hmacLen, buffer->end());
   setOutputBuffer(std::move(buffer));
diff --git a/ndn-cxx/security/transform/private-key.cpp b/ndn-cxx/security/transform/private-key.cpp
index 98358b8..91bfbeb 100644
--- a/ndn-cxx/security/transform/private-key.cpp
+++ b/ndn-cxx/security/transform/private-key.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -35,13 +35,13 @@
 #define ENSURE_PRIVATE_KEY_LOADED(key) \
   do { \
     if ((key) == nullptr) \
-      BOOST_THROW_EXCEPTION(Error("Private key has not been loaded yet")); \
+      NDN_THROW(Error("Private key has not been loaded yet")); \
   } while (false)
 
 #define ENSURE_PRIVATE_KEY_NOT_LOADED(key) \
   do { \
     if ((key) != nullptr) \
-      BOOST_THROW_EXCEPTION(Error("Private key has already been loaded")); \
+      NDN_THROW(Error("Private key has already been loaded")); \
   } while (false)
 
 namespace ndn {
@@ -107,7 +107,7 @@
   opensslInitAlgorithms();
 
   if (d2i_AutoPrivateKey(&m_impl->key, &buf, static_cast<long>(size)) == nullptr)
-    BOOST_THROW_EXCEPTION(Error("Failed to load private key"));
+    NDN_THROW(Error("Failed to load private key"));
 }
 
 void
@@ -143,10 +143,10 @@
 
   detail::Bio membio(BIO_s_mem());
   if (!membio.write(buf, size))
-    BOOST_THROW_EXCEPTION(Error("Failed to copy buffer"));
+    NDN_THROW(Error("Failed to copy buffer"));
 
   if (d2i_PKCS8PrivateKey_bio(membio, &m_impl->key, nullptr, const_cast<char*>(pw)) == nullptr)
-    BOOST_THROW_EXCEPTION(Error("Failed to load private key"));
+    NDN_THROW(Error("Failed to load private key"));
 }
 
 static inline int
@@ -165,7 +165,7 @@
 
   detail::Bio membio(BIO_s_mem());
   if (!membio.write(buf, size))
-    BOOST_THROW_EXCEPTION(Error("Failed to copy buffer"));
+    NDN_THROW(Error("Failed to copy buffer"));
 
   if (pwCallback)
     m_impl->key = d2i_PKCS8PrivateKey_bio(membio, nullptr, &passwordCallbackWrapper, &pwCallback);
@@ -173,7 +173,7 @@
     m_impl->key = d2i_PKCS8PrivateKey_bio(membio, nullptr, nullptr, nullptr);
 
   if (m_impl->key == nullptr)
-    BOOST_THROW_EXCEPTION(Error("Failed to load private key"));
+    NDN_THROW(Error("Failed to load private key"));
 }
 
 void
@@ -268,7 +268,7 @@
   uint8_t* pkcs8 = nullptr;
   int len = i2d_PUBKEY(m_impl->key, &pkcs8);
   if (len < 0)
-    BOOST_THROW_EXCEPTION(Error("Failed to derive public key"));
+    NDN_THROW(Error("Failed to derive public key"));
 
   auto result = make_shared<Buffer>(pkcs8, len);
   OPENSSL_free(pkcs8);
@@ -284,11 +284,11 @@
   int keyType = detail::getEvpPkeyType(m_impl->key);
   switch (keyType) {
     case EVP_PKEY_NONE:
-      BOOST_THROW_EXCEPTION(Error("Failed to determine key type"));
+      NDN_THROW(Error("Failed to determine key type"));
     case EVP_PKEY_RSA:
       return rsaDecrypt(cipherText, cipherLen);
     default:
-      BOOST_THROW_EXCEPTION(Error("Decryption is not supported for key type " + to_string(keyType)));
+      NDN_THROW(Error("Decryption is not supported for key type " + to_string(keyType)));
   }
 }
 
@@ -306,7 +306,7 @@
 
   detail::Bio membio(BIO_s_mem());
   if (!i2d_PrivateKey_bio(membio, m_impl->key))
-    BOOST_THROW_EXCEPTION(Error("Cannot convert key to PKCS #1 format"));
+    NDN_THROW(Error("Cannot convert key to PKCS #1 format"));
 
   auto buffer = make_shared<Buffer>(BIO_pending(membio));
   membio.read(buffer->data(), buffer->size());
@@ -324,7 +324,7 @@
   detail::Bio membio(BIO_s_mem());
   if (!i2d_PKCS8PrivateKey_bio(membio, m_impl->key, EVP_aes_256_cbc(), nullptr, 0,
                                nullptr, const_cast<char*>(pw)))
-    BOOST_THROW_EXCEPTION(Error("Cannot convert key to PKCS #8 format"));
+    NDN_THROW(Error("Cannot convert key to PKCS #8 format"));
 
   auto buffer = make_shared<Buffer>(BIO_pending(membio));
   membio.read(buffer->data(), buffer->size());
@@ -341,7 +341,7 @@
   detail::Bio membio(BIO_s_mem());
   if (!i2d_PKCS8PrivateKey_bio(membio, m_impl->key, EVP_aes_256_cbc(), nullptr, 0,
                                &passwordCallbackWrapper, &pwCallback))
-    BOOST_THROW_EXCEPTION(Error("Cannot convert key to PKCS #8 format"));
+    NDN_THROW(Error("Cannot convert key to PKCS #8 format"));
 
   auto buffer = make_shared<Buffer>(BIO_pending(membio));
   membio.read(buffer->data(), buffer->size());
@@ -355,19 +355,19 @@
   detail::EvpPkeyCtx ctx(m_impl->key);
 
   if (EVP_PKEY_decrypt_init(ctx) <= 0)
-    BOOST_THROW_EXCEPTION(Error("Failed to initialize decryption context"));
+    NDN_THROW(Error("Failed to initialize decryption context"));
 
   if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
-    BOOST_THROW_EXCEPTION(Error("Failed to set padding"));
+    NDN_THROW(Error("Failed to set padding"));
 
   size_t outlen = 0;
   // Determine buffer length
   if (EVP_PKEY_decrypt(ctx, nullptr, &outlen, cipherText, cipherLen) <= 0)
-    BOOST_THROW_EXCEPTION(Error("Failed to estimate output length"));
+    NDN_THROW(Error("Failed to estimate output length"));
 
   auto out = make_shared<Buffer>(outlen);
   if (EVP_PKEY_decrypt(ctx, out->data(), &outlen, cipherText, cipherLen) <= 0)
-    BOOST_THROW_EXCEPTION(Error("Failed to decrypt ciphertext"));
+    NDN_THROW(Error("Failed to decrypt ciphertext"));
 
   out->resize(outlen);
   return out;
@@ -379,14 +379,14 @@
   detail::EvpPkeyCtx kctx(EVP_PKEY_RSA);
 
   if (EVP_PKEY_keygen_init(kctx) <= 0)
-    BOOST_THROW_EXCEPTION(PrivateKey::Error("Failed to initialize RSA keygen context"));
+    NDN_THROW(PrivateKey::Error("Failed to initialize RSA keygen context"));
 
   if (EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, static_cast<int>(keySize)) <= 0)
-    BOOST_THROW_EXCEPTION(PrivateKey::Error("Failed to set RSA key length"));
+    NDN_THROW(PrivateKey::Error("Failed to set RSA key length"));
 
   auto privateKey = make_unique<PrivateKey>();
   if (EVP_PKEY_keygen(kctx, &privateKey->m_impl->key) <= 0)
-    BOOST_THROW_EXCEPTION(PrivateKey::Error("Failed to generate RSA key"));
+    NDN_THROW(PrivateKey::Error("Failed to generate RSA key"));
 
   return privateKey;
 }
@@ -397,7 +397,7 @@
   detail::EvpPkeyCtx pctx(EVP_PKEY_EC);
 
   if (EVP_PKEY_paramgen_init(pctx) <= 0)
-    BOOST_THROW_EXCEPTION(PrivateKey::Error("Failed to initialize EC paramgen context"));
+    NDN_THROW(PrivateKey::Error("Failed to initialize EC paramgen context"));
 
   int ret;
   switch (keySize) {
@@ -414,22 +414,22 @@
     ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp521r1);
     break;
   default:
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Unsupported EC key length " + to_string(keySize)));
+    NDN_THROW(std::invalid_argument("Unsupported EC key length " + to_string(keySize)));
   }
   if (ret <= 0)
-    BOOST_THROW_EXCEPTION(PrivateKey::Error("Failed to set EC curve"));
+    NDN_THROW(PrivateKey::Error("Failed to set EC curve"));
 
   Impl params;
   if (EVP_PKEY_paramgen(pctx, &params.key) <= 0)
-    BOOST_THROW_EXCEPTION(PrivateKey::Error("Failed to generate EC parameters"));
+    NDN_THROW(PrivateKey::Error("Failed to generate EC parameters"));
 
   detail::EvpPkeyCtx kctx(params.key);
   if (EVP_PKEY_keygen_init(kctx) <= 0)
-    BOOST_THROW_EXCEPTION(PrivateKey::Error("Failed to initialize EC keygen context"));
+    NDN_THROW(PrivateKey::Error("Failed to initialize EC keygen context"));
 
   auto privateKey = make_unique<PrivateKey>();
   if (EVP_PKEY_keygen(kctx, &privateKey->m_impl->key) <= 0)
-    BOOST_THROW_EXCEPTION(PrivateKey::Error("Failed to generate EC key"));
+    NDN_THROW(PrivateKey::Error("Failed to generate EC key"));
 
   return privateKey;
 }
@@ -447,8 +447,8 @@
       return PrivateKey::generateEcKey(ecParams.getKeySize());
     }
     default:
-      BOOST_THROW_EXCEPTION(std::invalid_argument("Unsupported asymmetric key type " +
-                                                  boost::lexical_cast<std::string>(keyParams.getKeyType())));
+      NDN_THROW(std::invalid_argument("Unsupported asymmetric key type " +
+                                      boost::lexical_cast<std::string>(keyParams.getKeyType())));
   }
 }
 
diff --git a/ndn-cxx/security/transform/public-key.cpp b/ndn-cxx/security/transform/public-key.cpp
index d6f8b20..d38b1d7 100644
--- a/ndn-cxx/security/transform/public-key.cpp
+++ b/ndn-cxx/security/transform/public-key.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -31,13 +31,13 @@
 #define ENSURE_PUBLIC_KEY_LOADED(key) \
   do { \
     if ((key) == nullptr) \
-      BOOST_THROW_EXCEPTION(Error("Public key has not been loaded yet")); \
+      NDN_THROW(Error("Public key has not been loaded yet")); \
   } while (false)
 
 #define ENSURE_PUBLIC_KEY_NOT_LOADED(key) \
   do { \
     if ((key) != nullptr) \
-      BOOST_THROW_EXCEPTION(Error("Public key has already been loaded")); \
+      NDN_THROW(Error("Public key has already been loaded")); \
   } while (false)
 
 namespace ndn {
@@ -90,7 +90,7 @@
   ENSURE_PUBLIC_KEY_NOT_LOADED(m_impl->key);
 
   if (d2i_PUBKEY(&m_impl->key, &buf, static_cast<long>(size)) == nullptr)
-    BOOST_THROW_EXCEPTION(Error("Failed to load public key"));
+    NDN_THROW(Error("Failed to load public key"));
 }
 
 void
@@ -137,11 +137,11 @@
   int keyType = detail::getEvpPkeyType(m_impl->key);
   switch (keyType) {
     case EVP_PKEY_NONE:
-      BOOST_THROW_EXCEPTION(Error("Failed to determine key type"));
+      NDN_THROW(Error("Failed to determine key type"));
     case EVP_PKEY_RSA:
       return rsaEncrypt(plainText, plainLen);
     default:
-      BOOST_THROW_EXCEPTION(Error("Encryption is not supported for key type " + to_string(keyType)));
+      NDN_THROW(Error("Encryption is not supported for key type " + to_string(keyType)));
   }
 }
 
@@ -159,7 +159,7 @@
   uint8_t* pkcs8 = nullptr;
   int len = i2d_PUBKEY(m_impl->key, &pkcs8);
   if (len < 0)
-    BOOST_THROW_EXCEPTION(Error("Cannot convert key to PKCS #8 format"));
+    NDN_THROW(Error("Cannot convert key to PKCS #8 format"));
 
   auto buffer = make_shared<Buffer>(pkcs8, len);
   OPENSSL_free(pkcs8);
@@ -173,19 +173,19 @@
   detail::EvpPkeyCtx ctx(m_impl->key);
 
   if (EVP_PKEY_encrypt_init(ctx) <= 0)
-    BOOST_THROW_EXCEPTION(Error("Failed to initialize encryption context"));
+    NDN_THROW(Error("Failed to initialize encryption context"));
 
   if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
-    BOOST_THROW_EXCEPTION(Error("Failed to set padding"));
+    NDN_THROW(Error("Failed to set padding"));
 
   size_t outlen = 0;
   // Determine buffer length
   if (EVP_PKEY_encrypt(ctx, nullptr, &outlen, plainText, plainLen) <= 0)
-    BOOST_THROW_EXCEPTION(Error("Failed to estimate output length"));
+    NDN_THROW(Error("Failed to estimate output length"));
 
   auto out = make_shared<Buffer>(outlen);
   if (EVP_PKEY_encrypt(ctx, out->data(), &outlen, plainText, plainLen) <= 0)
-    BOOST_THROW_EXCEPTION(Error("Failed to encrypt plaintext"));
+    NDN_THROW(Error("Failed to encrypt plaintext"));
 
   out->resize(outlen);
   return out;
diff --git a/ndn-cxx/security/transform/signer-filter.cpp b/ndn-cxx/security/transform/signer-filter.cpp
index b6ae6dd..33f380f 100644
--- a/ndn-cxx/security/transform/signer-filter.cpp
+++ b/ndn-cxx/security/transform/signer-filter.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -41,14 +41,14 @@
 {
   const EVP_MD* md = detail::digestAlgorithmToEvpMd(algo);
   if (md == nullptr)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported digest algorithm " +
-                                boost::lexical_cast<std::string>(algo)));
+    NDN_THROW(Error(getIndex(), "Unsupported digest algorithm " +
+                    boost::lexical_cast<std::string>(algo)));
 
   if (EVP_DigestSignInit(m_impl->ctx, nullptr, md, nullptr,
                          reinterpret_cast<EVP_PKEY*>(key.getEvpPkey())) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to initialize signing context with " +
-                                boost::lexical_cast<std::string>(algo) + " digest and " +
-                                boost::lexical_cast<std::string>(key.getKeyType()) + " key"));
+    NDN_THROW(Error(getIndex(), "Failed to initialize signing context with " +
+                    boost::lexical_cast<std::string>(algo) + " digest and " +
+                    boost::lexical_cast<std::string>(key.getKeyType()) + " key"));
 }
 
 SignerFilter::~SignerFilter() = default;
@@ -57,7 +57,7 @@
 SignerFilter::convert(const uint8_t* buf, size_t size)
 {
   if (EVP_DigestSignUpdate(m_impl->ctx, buf, size) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
+    NDN_THROW(Error(getIndex(), "Failed to accept more input"));
 
   return size;
 }
@@ -67,11 +67,11 @@
 {
   size_t sigLen = 0;
   if (EVP_DigestSignFinal(m_impl->ctx, nullptr, &sigLen) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to estimate buffer length"));
+    NDN_THROW(Error(getIndex(), "Failed to estimate buffer length"));
 
   auto buffer = make_unique<OBuffer>(sigLen);
   if (EVP_DigestSignFinal(m_impl->ctx, buffer->data(), &sigLen) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to finalize signature"));
+    NDN_THROW(Error(getIndex(), "Failed to finalize signature"));
 
   buffer->erase(buffer->begin() + sigLen, buffer->end());
   setOutputBuffer(std::move(buffer));
diff --git a/ndn-cxx/security/transform/stream-sink.cpp b/ndn-cxx/security/transform/stream-sink.cpp
index d8b25e7..5eba76a 100644
--- a/ndn-cxx/security/transform/stream-sink.cpp
+++ b/ndn-cxx/security/transform/stream-sink.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -38,7 +38,7 @@
   m_os.write(reinterpret_cast<const char*>(buf), size);
 
   if (m_os.bad())
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Fail to write data into output stream"));
+    NDN_THROW(Error(getIndex(), "Fail to write data into output stream"));
 
   return size;
 }
diff --git a/ndn-cxx/security/transform/stream-source.cpp b/ndn-cxx/security/transform/stream-source.cpp
index f86ba99..40fb7a4 100644
--- a/ndn-cxx/security/transform/stream-source.cpp
+++ b/ndn-cxx/security/transform/stream-source.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -56,7 +56,7 @@
       dataLen -= nBytesWritten;
     }
     else if (!m_is) {
-      BOOST_THROW_EXCEPTION(Error(getIndex(), "Input stream in bad state"));
+      NDN_THROW(Error(getIndex(), "Input stream in bad state"));
     }
     else if (m_is.good()) {
       m_is.read(reinterpret_cast<char*>(&buffer.front()), buffer.size());
diff --git a/ndn-cxx/security/transform/transform-base.cpp b/ndn-cxx/security/transform/transform-base.cpp
index 571a557..9bd661d 100644
--- a/ndn-cxx/security/transform/transform-base.cpp
+++ b/ndn-cxx/security/transform/transform-base.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -41,7 +41,7 @@
 Downstream::write(const uint8_t* buf, size_t size)
 {
   if (m_isEnd)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Module is closed, no more input"));
+    NDN_THROW(Error(getIndex(), "Module is closed, no more input"));
 
   size_t nBytesWritten = doWrite(buf, size);
   BOOST_ASSERT(nBytesWritten <= size);
diff --git a/ndn-cxx/security/transform/verifier-filter.cpp b/ndn-cxx/security/transform/verifier-filter.cpp
index 51eb4b4..98cb3c1 100644
--- a/ndn-cxx/security/transform/verifier-filter.cpp
+++ b/ndn-cxx/security/transform/verifier-filter.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -51,14 +51,14 @@
 {
   const EVP_MD* md = detail::digestAlgorithmToEvpMd(algo);
   if (md == nullptr)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported digest algorithm " +
-                                boost::lexical_cast<std::string>(algo)));
+    NDN_THROW(Error(getIndex(), "Unsupported digest algorithm " +
+                    boost::lexical_cast<std::string>(algo)));
 
   if (EVP_DigestVerifyInit(m_impl->ctx, nullptr, md, nullptr,
                            reinterpret_cast<EVP_PKEY*>(key.getEvpPkey())) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to initialize verification context with " +
-                                boost::lexical_cast<std::string>(algo) + " digest and " +
-                                boost::lexical_cast<std::string>(key.getKeyType()) + " key"));
+    NDN_THROW(Error(getIndex(), "Failed to initialize verification context with " +
+                    boost::lexical_cast<std::string>(algo) + " digest and " +
+                    boost::lexical_cast<std::string>(key.getKeyType()) + " key"));
 }
 
 VerifierFilter::~VerifierFilter() = default;
@@ -67,7 +67,7 @@
 VerifierFilter::convert(const uint8_t* buf, size_t size)
 {
   if (EVP_DigestVerifyUpdate(m_impl->ctx, buf, size) != 1)
-    BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
+    NDN_THROW(Error(getIndex(), "Failed to accept more input"));
 
   return size;
 }
diff --git a/ndn-cxx/security/v2/additional-description.cpp b/ndn-cxx/security/v2/additional-description.cpp
index 143ce2c..d885cca 100644
--- a/ndn-cxx/security/v2/additional-description.cpp
+++ b/ndn-cxx/security/v2/additional-description.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -47,7 +47,7 @@
 {
   auto it = m_info.find(key);
   if (it == m_info.end())
-    BOOST_THROW_EXCEPTION(Error("Entry does not exist for key (" + key + ")"));
+    NDN_THROW(Error("Entry does not exist for key (" + key + ")"));
 
   return it->second;
 }
@@ -133,29 +133,29 @@
 AdditionalDescription::wireDecode(const Block& wire)
 {
    if (!wire.hasWire()) {
-     BOOST_THROW_EXCEPTION(Error("The supplied block does not contain wire format"));
+     NDN_THROW(Error("The supplied block does not contain wire format"));
   }
 
   m_wire = wire;
   m_wire.parse();
 
   if (m_wire.type() != tlv::AdditionalDescription)
-    BOOST_THROW_EXCEPTION(Error("Unexpected TLV type when decoding AdditionalDescription"));
+    NDN_THROW(Error("AdditionalDescription", m_wire.type()));
 
-  Block::element_const_iterator it = m_wire.elements_begin();
+  auto it = m_wire.elements_begin();
   while (it != m_wire.elements_end()) {
     const Block& entry = *it;
     entry.parse();
 
     if (entry.type() != tlv::DescriptionEntry)
-      BOOST_THROW_EXCEPTION(Error("Unexpected TLV type when decoding DescriptionEntry"));
+      NDN_THROW(Error("DescriptionEntry", entry.type()));
 
     if (entry.elements_size() != 2)
-      BOOST_THROW_EXCEPTION(Error("DescriptionEntry does not have two sub-TLVs"));
+      NDN_THROW(Error("DescriptionEntry does not have two sub-TLVs"));
 
     if (entry.elements()[KEY_OFFSET].type() != tlv::DescriptionKey ||
         entry.elements()[VALUE_OFFSET].type() != tlv::DescriptionValue)
-      BOOST_THROW_EXCEPTION(Error("Invalid DescriptionKey or DescriptionValue field"));
+      NDN_THROW(Error("Invalid DescriptionKey or DescriptionValue field"));
 
     m_info[readString(entry.elements()[KEY_OFFSET])] = readString(entry.elements()[VALUE_OFFSET]);
     it++;
diff --git a/ndn-cxx/security/v2/certificate.cpp b/ndn-cxx/security/v2/certificate.cpp
index 03e40cf..9883825 100644
--- a/ndn-cxx/security/v2/certificate.cpp
+++ b/ndn-cxx/security/v2/certificate.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -47,23 +47,23 @@
 
 Certificate::Certificate()
 {
-  setContentType(tlv::ContentTypeValue::ContentType_Key);
+  setContentType(tlv::ContentType_Key);
 }
 
 Certificate::Certificate(Data&& data)
   : Data(data)
 {
   if (!isValidName(getName())) {
-    BOOST_THROW_EXCEPTION(Data::Error("Name does not follow the naming convention for certificate"));
+    NDN_THROW(Data::Error("Name does not follow the naming convention for certificate"));
   }
-  if (getContentType() != tlv::ContentTypeValue::ContentType_Key) {
-    BOOST_THROW_EXCEPTION(Data::Error("ContentType is not KEY"));
+  if (getContentType() != tlv::ContentType_Key) {
+    NDN_THROW(Data::Error("Expecting ContentType Key, got " + to_string(getContentType())));
   }
   if (getFreshnessPeriod() < time::seconds::zero()) {
-    BOOST_THROW_EXCEPTION(Data::Error("FreshnessPeriod is not set"));
+    NDN_THROW(Data::Error("FreshnessPeriod is not set"));
   }
   if (getContent().value_size() == 0) {
-    BOOST_THROW_EXCEPTION(Data::Error("Content is empty"));
+    NDN_THROW(Data::Error("Content is empty"));
   }
 }
 
@@ -105,7 +105,7 @@
 Certificate::getPublicKey() const
 {
   if (getContent().value_size() == 0)
-    BOOST_THROW_EXCEPTION(Data::Error("Content is empty"));
+    NDN_THROW(Data::Error("Content is empty"));
   return Buffer(getContent().value(), getContent().value_size());
 }
 
@@ -185,8 +185,8 @@
 extractIdentityFromCertName(const Name& certName)
 {
   if (!Certificate::isValidName(certName)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
-                                                "does not follow the naming conventions"));
+    NDN_THROW(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
+                                    "does not respect the naming conventions"));
   }
 
   return certName.getPrefix(Certificate::KEY_COMPONENT_OFFSET); // trim everything after and including "KEY"
@@ -196,8 +196,8 @@
 extractKeyNameFromCertName(const Name& certName)
 {
   if (!Certificate::isValidName(certName)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
-                                                "does not follow the naming conventions"));
+    NDN_THROW(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
+                                    "does not respect the naming conventions"));
   }
 
   return certName.getPrefix(Certificate::KEY_ID_OFFSET + 1); // trim everything after key id
diff --git a/ndn-cxx/security/v2/key-chain.cpp b/ndn-cxx/security/v2/key-chain.cpp
index 6ea29ca..8043635 100644
--- a/ndn-cxx/security/v2/key-chain.cpp
+++ b/ndn-cxx/security/v2/key-chain.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -202,8 +202,8 @@
       if (allowReset)
         m_pib->reset();
       else
-        BOOST_THROW_EXCEPTION(LocatorMismatchError("TPM locator supplied does not match TPM locator in PIB: " +
-                                                   oldTpmLocator + " != " + canonicalTpmLocator));
+        NDN_THROW(LocatorMismatchError("TPM locator supplied does not match TPM locator in PIB: " +
+                                       oldTpmLocator + " != " + canonicalTpmLocator));
     }
   }
 
@@ -290,8 +290,8 @@
 
   Name keyName = key.getName();
   if (identity.getName() != key.getIdentity()) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Identity `" + identity.getName().toUri() + "` "
-                                                "does not match key `" + keyName.toUri() + "`"));
+    NDN_THROW(std::invalid_argument("Identity `" + identity.getName().toUri() + "` "
+                                    "does not match key `" + keyName.toUri() + "`"));
   }
 
   identity.removeKey(keyName);
@@ -305,8 +305,8 @@
   BOOST_ASSERT(static_cast<bool>(key));
 
   if (identity.getName() != key.getIdentity())
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Identity `" + identity.getName().toUri() + "` "
-                                                "does not match key `" + key.getName().toUri() + "`"));
+    NDN_THROW(std::invalid_argument("Identity `" + identity.getName().toUri() + "` "
+                                    "does not match key `" + key.getName().toUri() + "`"));
 
   identity.setDefaultKey(key.getName());
 }
@@ -319,8 +319,8 @@
   if (key.getName() != certificate.getKeyName() ||
       !std::equal(certificate.getContent().value_begin(), certificate.getContent().value_end(),
                   key.getPublicKey().begin()))
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Key `" + key.getName().toUri() + "` "
-                                                "does not match certificate `" + certificate.getName().toUri() + "`"));
+    NDN_THROW(std::invalid_argument("Key `" + key.getName().toUri() + "` "
+                                    "does not match certificate `" + certificate.getName().toUri() + "`"));
 
   key.addCertificate(certificate);
 }
@@ -331,7 +331,7 @@
   BOOST_ASSERT(static_cast<bool>(key));
 
   if (!Certificate::isValidName(certificateName)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Wrong certificate name `" + certificateName.toUri() + "`"));
+    NDN_THROW(std::invalid_argument("Wrong certificate name `" + certificateName.toUri() + "`"));
   }
 
   key.removeCertificate(certificateName);
@@ -356,8 +356,8 @@
   try {
     encryptedKey = m_tpm->exportPrivateKey(keyName, pw, pwLen);
   }
-  catch (const tpm::BackEnd::Error& e) {
-    BOOST_THROW_EXCEPTION(Error("Failed to export private key `" + keyName.toUri() + "`: " + e.what()));
+  catch (const tpm::BackEnd::Error&) {
+    NDN_THROW_NESTED(Error("Failed to export private key `" + keyName.toUri() + "`"));
   }
 
   return make_shared<SafeBag>(certificate, *encryptedKey);
@@ -373,13 +373,13 @@
   const Buffer publicKeyBits = cert.getPublicKey();
 
   if (m_tpm->hasKey(keyName)) {
-    BOOST_THROW_EXCEPTION(Error("Private key `" + keyName.toUri() + "` already exists"));
+    NDN_THROW(Error("Private key `" + keyName.toUri() + "` already exists"));
   }
 
   try {
     Identity existingId = m_pib->getIdentity(identity);
     existingId.getKey(keyName);
-    BOOST_THROW_EXCEPTION(Error("Public key `" + keyName.toUri() + "` already exists"));
+    NDN_THROW(Error("Public key `" + keyName.toUri() + "` already exists"));
   }
   catch (const Pib::Error&) {
     // Either identity or key doesn't exist. OK to import.
@@ -390,8 +390,8 @@
                             safeBag.getEncryptedKeyBag().data(), safeBag.getEncryptedKeyBag().size(),
                             pw, pwLen);
   }
-  catch (const tpm::BackEnd::Error& e) {
-    BOOST_THROW_EXCEPTION(Error("Failed to import private key `" + keyName.toUri() + "`: " + e.what()));
+  catch (const tpm::BackEnd::Error&) {
+    NDN_THROW_NESTED(Error("Failed to import private key `" + keyName.toUri() + "`"));
   }
 
   // check the consistency of private key and certificate
@@ -402,7 +402,7 @@
   }
   catch (const std::runtime_error&) {
     m_tpm->deleteKey(keyName);
-    BOOST_THROW_EXCEPTION(Error("Invalid private key `" + keyName.toUri() + "`"));
+    NDN_THROW(Error("Invalid private key `" + keyName.toUri() + "`"));
   }
   bool isVerified = false;
   {
@@ -415,8 +415,8 @@
   }
   if (!isVerified) {
     m_tpm->deleteKey(keyName);
-    BOOST_THROW_EXCEPTION(Error("Certificate `" + cert.getName().toUri() + "` "
-                                "and private key `" + keyName.toUri() + "` do not match"));
+    NDN_THROW(Error("Certificate `" + cert.getName().toUri() + "` "
+                    "and private key `" + keyName.toUri() + "` do not match"));
   }
 
   Identity id = m_pib->addIdentity(identity);
@@ -497,7 +497,7 @@
 
   auto pibFactory = getPibFactories().find(pibScheme);
   if (pibFactory == getPibFactories().end()) {
-    BOOST_THROW_EXCEPTION(KeyChain::Error("PIB scheme `" + pibScheme + "` is not supported"));
+    NDN_THROW(KeyChain::Error("PIB scheme `" + pibScheme + "` is not supported"));
   }
 
   return std::make_tuple(pibScheme, pibLocation);
@@ -524,7 +524,7 @@
   }
   auto tpmFactory = getTpmFactories().find(tpmScheme);
   if (tpmFactory == getTpmFactories().end()) {
-    BOOST_THROW_EXCEPTION(KeyChain::Error("TPM scheme `" + tpmScheme + "` is not supported"));
+    NDN_THROW(KeyChain::Error("TPM scheme `" + tpmScheme + "` is not supported"));
   }
 
   return std::make_tuple(tpmScheme, tpmLocation);
@@ -578,11 +578,8 @@
 KeyChain::prepareSignatureInfo(const SigningInfo& params)
 {
   SignatureInfo sigInfo = params.getSignatureInfo();
-
-  Name identityName;
   name::Component keyId;
   Name certificateName;
-
   pib::Identity identity;
   pib::Key key;
 
@@ -604,8 +601,8 @@
           identity = m_pib->getIdentity(params.getSignerName());
         }
         catch (const Pib::Error&) {
-          BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing identity `" +
-                                                        params.getSignerName().toUri() + "` does not exist"));
+          NDN_THROW_NESTED(InvalidSigningInfoError("Signing identity `" +
+                                                   params.getSignerName().toUri() + "` does not exist"));
         }
       }
       break;
@@ -614,15 +611,14 @@
       key = params.getPibKey();
       if (!key) {
         Name identityName = extractIdentityFromKeyName(params.getSignerName());
-
         try {
           identity = m_pib->getIdentity(identityName);
           key = identity.getKey(params.getSignerName());
           identity = Identity(); // we will use the PIB key instance, so reset identity;
         }
         catch (const Pib::Error&) {
-          BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing key `" +
-                                                        params.getSignerName().toUri() + "` does not exist"));
+          NDN_THROW_NESTED(InvalidSigningInfoError("Signing key `" +
+                                                   params.getSignerName().toUri() + "` does not exist"));
         }
       }
       break;
@@ -630,16 +626,14 @@
     case SigningInfo::SIGNER_TYPE_CERT: {
       Name identityName = extractIdentityFromCertName(params.getSignerName());
       Name keyName = extractKeyNameFromCertName(params.getSignerName());
-
       try {
         identity = m_pib->getIdentity(identityName);
         key = identity.getKey(keyName);
       }
       catch (const Pib::Error&) {
-        BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing certificate `" +
-                                                      params.getSignerName().toUri() + "` does not exist"));
+        NDN_THROW_NESTED(InvalidSigningInfoError("Signing certificate `" +
+                                                 params.getSignerName().toUri() + "` does not exist"));
       }
-
       break;
     }
     case SigningInfo::SIGNER_TYPE_SHA256: {
@@ -647,13 +641,13 @@
       return std::make_tuple(SigningInfo::getDigestSha256Identity(), sigInfo);
     }
     default: {
-      BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Unrecognized signer type " +
-                                                    boost::lexical_cast<std::string>(params.getSignerType())));
+      NDN_THROW(InvalidSigningInfoError("Unrecognized signer type " +
+                                        boost::lexical_cast<std::string>(params.getSignerType())));
     }
   }
 
   if (!identity && !key) {
-    BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Cannot determine signing parameters"));
+    NDN_THROW(InvalidSigningInfoError("Cannot determine signing parameters"));
   }
 
   if (identity && !key) {
@@ -661,8 +655,8 @@
       key = identity.getDefaultKey();
     }
     catch (const Pib::Error&) {
-      BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing identity `" + identity.getName().toUri() +
-                                                    "` does not have a default certificate"));
+      NDN_THROW_NESTED(InvalidSigningInfoError("Signing identity `" + identity.getName().toUri() +
+                                               "` does not have a default certificate"));
     }
   }
 
@@ -686,7 +680,7 @@
 }
 
 tlv::SignatureTypeValue
-KeyChain::getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm)
+KeyChain::getSignatureType(KeyType keyType, DigestAlgorithm)
 {
   switch (keyType) {
   case KeyType::RSA:
@@ -694,7 +688,7 @@
   case KeyType::EC:
     return tlv::SignatureSha256WithEcdsa;
   default:
-    BOOST_THROW_EXCEPTION(Error("Unsupported key types"));
+    NDN_THROW(Error("Unsupported key type " + boost::lexical_cast<std::string>(keyType)));
   }
 }
 
diff --git a/ndn-cxx/security/v2/trust-anchor-container.cpp b/ndn-cxx/security/v2/trust-anchor-container.cpp
index c6c5e63..f77f233 100644
--- a/ndn-cxx/security/v2/trust-anchor-container.cpp
+++ b/ndn-cxx/security/v2/trust-anchor-container.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -54,7 +54,7 @@
   }
   auto* staticGroup = dynamic_cast<StaticTrustAnchorGroup*>(&**group);
   if (staticGroup == nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Cannot add static anchor to a non-static anchor group " + groupId));
+    NDN_THROW(Error("Cannot add static anchor to a non-static anchor group " + groupId));
   }
   staticGroup->add(std::move(cert));
 }
@@ -64,7 +64,7 @@
                              time::nanoseconds refreshPeriod, bool isDir)
 {
   if (m_groups.count(groupId) != 0) {
-    BOOST_THROW_EXCEPTION(Error("Cannot create dynamic group, because group " + groupId + " already exists"));
+    NDN_THROW(Error("Cannot create dynamic group, because group " + groupId + " already exists"));
   }
 
   m_groups.insert(make_shared<DynamicTrustAnchorGroup>(m_anchors, groupId, path, refreshPeriod, isDir));
@@ -109,7 +109,7 @@
 {
   auto group = m_groups.find(groupId);
   if (group == m_groups.end()) {
-    BOOST_THROW_EXCEPTION(Error("Trust anchor group " + groupId + " does not exist"));
+    NDN_THROW(Error("Trust anchor group " + groupId + " does not exist"));
   }
   return **group;
 }
diff --git a/ndn-cxx/security/v2/trust-anchor-group.cpp b/ndn-cxx/security/v2/trust-anchor-group.cpp
index 54a4bb8..1c27a41 100644
--- a/ndn-cxx/security/v2/trust-anchor-group.cpp
+++ b/ndn-cxx/security/v2/trust-anchor-group.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -92,7 +92,7 @@
   , m_refreshPeriod(refreshPeriod)
 {
   if (refreshPeriod <= time::nanoseconds::zero()) {
-    BOOST_THROW_EXCEPTION(std::runtime_error("Refresh period for the dynamic group must be positive"));
+    NDN_THROW(std::runtime_error("Refresh period for the dynamic group must be positive"));
   }
 
   NDN_LOG_TRACE("Create dynamic trust anchor group " << id << " for file/dir " << path
diff --git a/ndn-cxx/security/v2/validation-error.hpp b/ndn-cxx/security/v2/validation-error.hpp
index 9a3a7d8..826cd18 100644
--- a/ndn-cxx/security/v2/validation-error.hpp
+++ b/ndn-cxx/security/v2/validation-error.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -57,7 +57,7 @@
   /**
    * @brief Validation error, implicitly convertible from an error code and info
    */
-  ValidationError(uint32_t code,  const std::string& info = "")
+  ValidationError(uint32_t code, const std::string& info = "")
     : m_code(code)
     , m_info(info)
   {
diff --git a/ndn-cxx/security/v2/validation-policy-command-interest.cpp b/ndn-cxx/security/v2/validation-policy-command-interest.cpp
index 7a0d0a4..52f276d 100644
--- a/ndn-cxx/security/v2/validation-policy-command-interest.cpp
+++ b/ndn-cxx/security/v2/validation-policy-command-interest.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -32,7 +32,7 @@
   , m_queue(m_container.get<1>())
 {
   if (inner == nullptr) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("inner policy is missing"));
+    NDN_THROW(std::invalid_argument("inner policy is missing"));
   }
   setInnerPolicy(std::move(inner));
 
diff --git a/ndn-cxx/security/v2/validation-policy-config.cpp b/ndn-cxx/security/v2/validation-policy-config.cpp
index d3d0476..29d6f8c 100644
--- a/ndn-cxx/security/v2/validation-policy-config.cpp
+++ b/ndn-cxx/security/v2/validation-policy-config.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -46,7 +46,7 @@
 {
   std::ifstream inputFile(filename);
   if (!inputFile) {
-    BOOST_THROW_EXCEPTION(Error("Failed to read configuration file: " + filename));
+    NDN_THROW(Error("Failed to read configuration file: " + filename));
   }
   load(inputFile, filename);
 }
@@ -66,8 +66,8 @@
     boost::property_tree::read_info(input, tree);
   }
   catch (const boost::property_tree::info_parser_error& e) {
-    BOOST_THROW_EXCEPTION(Error("Failed to parse configuration file " + filename +
-                                " line " + to_string(e.line()) + ": " + e.message()));
+    NDN_THROW(Error("Failed to parse configuration file " + filename +
+                    " line " + to_string(e.line()) + ": " + e.message()));
   }
   load(tree, filename);
 }
@@ -76,7 +76,7 @@
 ValidationPolicyConfig::load(const ConfigSection& configSection, const std::string& filename)
 {
   if (m_validator == nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Validator instance not assigned on the policy"));
+    NDN_THROW(Error("Validator instance not assigned on the policy"));
   }
   if (m_isConfigured) {
     m_shouldBypass = false;
@@ -90,7 +90,7 @@
   BOOST_ASSERT(!filename.empty());
 
   if (configSection.begin() == configSection.end()) {
-    BOOST_THROW_EXCEPTION(Error("Error processing configuration file " + filename + ": no data"));
+    NDN_THROW(Error("Error processing configuration file " + filename + ": no data"));
   }
 
   for (const auto& subSection : configSection) {
@@ -110,8 +110,8 @@
       processConfigTrustAnchor(section, filename);
     }
     else {
-      BOOST_THROW_EXCEPTION(Error("Error processing configuration file " + filename +
-                                  ": unrecognized section " + sectionName));
+      NDN_THROW(Error("Error processing configuration file " + filename +
+                      ": unrecognized section " + sectionName));
     }
   }
 }
@@ -126,7 +126,7 @@
 
   // Get trust-anchor.type
   if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
-    BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.type>"));
+    NDN_THROW(Error("Expecting <trust-anchor.type>"));
   }
 
   std::string type = propertyIt->second.data();
@@ -135,7 +135,7 @@
   if (boost::iequals(type, "file")) {
     // Get trust-anchor.file
     if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "file-name")) {
-      BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.file-name>"));
+      NDN_THROW(Error("Expecting <trust-anchor.file-name>"));
     }
 
     std::string file = propertyIt->second.data();
@@ -143,7 +143,7 @@
 
     time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
     if (propertyIt != configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expecting end of <trust-anchor>"));
+      NDN_THROW(Error("Expecting end of <trust-anchor>"));
 
     m_validator->loadAnchor(filename, absolute(file, path(filename).parent_path()).string(),
                             refresh, false);
@@ -151,32 +151,32 @@
   else if (boost::iequals(type, "base64")) {
     // Get trust-anchor.base64-string
     if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "base64-string"))
-      BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.base64-string>"));
+      NDN_THROW(Error("Expecting <trust-anchor.base64-string>"));
 
     std::stringstream ss(propertyIt->second.data());
     propertyIt++;
 
     if (propertyIt != configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expecting end of <trust-anchor>"));
+      NDN_THROW(Error("Expecting end of <trust-anchor>"));
 
     auto idCert = io::load<Certificate>(ss);
     if (idCert != nullptr) {
       m_validator->loadAnchor("", std::move(*idCert));
     }
     else {
-      BOOST_THROW_EXCEPTION(Error("Cannot decode certificate from base64-string"));
+      NDN_THROW(Error("Cannot decode certificate from base64-string"));
     }
   }
   else if (boost::iequals(type, "dir")) {
     if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "dir"))
-      BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.dir>"));
+      NDN_THROW(Error("Expecting <trust-anchor.dir>"));
 
     std::string dirString(propertyIt->second.data());
     propertyIt++;
 
     time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
     if (propertyIt != configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expecting end of <trust-anchor>"));
+      NDN_THROW(Error("Expecting end of <trust-anchor>"));
 
     path dirPath = absolute(dirString, path(filename).parent_path());
     m_validator->loadAnchor(dirString, dirPath.string(), refresh, true);
@@ -185,7 +185,7 @@
     m_shouldBypass = true;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("Unrecognized <trust-anchor.type>: " + type));
+    NDN_THROW(Error("Unrecognized <trust-anchor.type>: " + type));
   }
 }
 
@@ -199,7 +199,7 @@
   }
 
   if (!boost::iequals(it->first, "refresh")) {
-    BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.refresh>"));
+    NDN_THROW(Error("Expecting <trust-anchor.refresh>"));
   }
 
   std::string inputString = it->second.data();
@@ -215,7 +215,7 @@
     // pass
   }
   if (refreshPeriod < 0) {
-    BOOST_THROW_EXCEPTION(Error("Bad refresh value: " + refreshString));
+    NDN_THROW(Error("Bad refresh value: " + refreshString));
   }
 
   if (refreshPeriod == 0) {
@@ -230,7 +230,7 @@
     case 's':
       return time::seconds(refreshPeriod);
     default:
-      BOOST_THROW_EXCEPTION(Error("Bad refresh time unit: "s + unit));
+      NDN_THROW(Error("Bad refresh time unit: "s + unit));
   }
 }
 
diff --git a/ndn-cxx/security/v2/validation-policy.cpp b/ndn-cxx/security/v2/validation-policy.cpp
index 8a235af..f182108 100644
--- a/ndn-cxx/security/v2/validation-policy.cpp
+++ b/ndn-cxx/security/v2/validation-policy.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -30,7 +30,7 @@
 ValidationPolicy::setInnerPolicy(unique_ptr<ValidationPolicy> innerPolicy)
 {
   if (innerPolicy == nullptr) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Inner policy argument cannot be nullptr"));
+    NDN_THROW(std::invalid_argument("Inner policy argument cannot be nullptr"));
   }
 
   if (m_validator != nullptr) {
diff --git a/ndn-cxx/security/v2/validator-config/checker.cpp b/ndn-cxx/security/v2/validator-config/checker.cpp
index f39b8ef..db07441 100644
--- a/ndn-cxx/security/v2/validator-config/checker.cpp
+++ b/ndn-cxx/security/v2/validator-config/checker.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -128,7 +128,7 @@
 
   // Get checker.type
   if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
-    BOOST_THROW_EXCEPTION(Error("Expecting <checker.type>"));
+    NDN_THROW(Error("Expecting <checker.type>"));
   }
 
   std::string type = propertyIt->second.data();
@@ -139,7 +139,7 @@
     return createHierarchicalChecker(configSection, configFilename);
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("Unrecognized <checker.type>: " + type));
+    NDN_THROW(Error("Unrecognized <checker.type>: " + type));
   }
 }
 
@@ -159,14 +159,14 @@
 
   // Get checker.key-locator
   if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "key-locator")) {
-    BOOST_THROW_EXCEPTION(Error("Expecting <checker.key-locator>"));
+    NDN_THROW(Error("Expecting <checker.key-locator>"));
   }
 
   auto checker = createKeyLocatorChecker(propertyIt->second, configFilename);
   propertyIt++;
 
   if (propertyIt != configSection.end()) {
-    BOOST_THROW_EXCEPTION(Error("Expecting end of <checker>"));
+    NDN_THROW(Error("Expecting end of <checker>"));
   }
   return checker;
 }
@@ -186,7 +186,7 @@
   }
 
   if (propertyIt != configSection.end()) {
-    BOOST_THROW_EXCEPTION(Error("Expecting end of <checker>"));
+    NDN_THROW(Error("Expecting end of <checker>"));
   }
   return make_unique<HyperRelationChecker>("^(<>*)$",        "\\1",
                                            "^(<>*)<KEY><>$", "\\1",
@@ -201,13 +201,13 @@
 
   // Get checker.key-locator.type
   if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
-    BOOST_THROW_EXCEPTION(Error("Expecting <checker.key-locator.type>"));
+    NDN_THROW(Error("Expecting <checker.key-locator.type>"));
 
   std::string type = propertyIt->second.data();
   if (boost::iequals(type, "name"))
     return createKeyLocatorNameChecker(configSection, configFilename);
   else
-    BOOST_THROW_EXCEPTION(Error("Unrecognized <checker.key-locator.type>: " + type));
+    NDN_THROW(Error("Unrecognized <checker.key-locator.type>: " + type));
 }
 
 unique_ptr<Checker>
@@ -218,7 +218,7 @@
   propertyIt++;
 
   if (propertyIt == configSection.end())
-    BOOST_THROW_EXCEPTION(Error("Unexpected end of <checker.key-locator>"));
+    NDN_THROW(Error("Unexpected end of <checker.key-locator>"));
 
   if (boost::iequals(propertyIt->first, "name")) {
     Name name;
@@ -226,12 +226,12 @@
       name = Name(propertyIt->second.data());
     }
     catch (const Name::Error&) {
-      BOOST_THROW_EXCEPTION(Error("Invalid <checker.key-locator.name>: " + propertyIt->second.data()));
+      NDN_THROW_NESTED(Error("Invalid <checker.key-locator.name>: " + propertyIt->second.data()));
     }
     propertyIt++;
 
     if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation")) {
-      BOOST_THROW_EXCEPTION(Error("Expecting <checker.key-locator.relation>"));
+      NDN_THROW(Error("Expecting <checker.key-locator.relation>"));
     }
 
     std::string relationString = propertyIt->second.data();
@@ -240,7 +240,7 @@
     NameRelation relation = getNameRelationFromString(relationString);
 
     if (propertyIt != configSection.end()) {
-      BOOST_THROW_EXCEPTION(Error("Expecting end of <checker.key-locator>"));
+      NDN_THROW(Error("Expecting end of <checker.key-locator>"));
     }
     return make_unique<NameRelationChecker>(name, relation);
   }
@@ -249,23 +249,23 @@
     propertyIt++;
 
     if (propertyIt != configSection.end()) {
-      BOOST_THROW_EXCEPTION(Error("Expecting end of <checker.key-locator>"));
+      NDN_THROW(Error("Expecting end of <checker.key-locator>"));
     }
 
     try {
       return make_unique<RegexChecker>(Regex(regexString));
     }
     catch (const Regex::Error&) {
-      BOOST_THROW_EXCEPTION(Error("Invalid <checker.key-locator.regex>: " + regexString));
+      NDN_THROW_NESTED(Error("Invalid <checker.key-locator.regex>: " + regexString));
     }
   }
   else if (boost::iequals(propertyIt->first, "hyper-relation")) {
     const ConfigSection& hSection = propertyIt->second;
-    ConfigSection::const_iterator hPropertyIt = hSection.begin();
+    auto hPropertyIt = hSection.begin();
 
     // Get k-regex
     if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-regex")) {
-      BOOST_THROW_EXCEPTION(Error("Expecting <checker.key-locator.hyper-relation.k-regex>"));
+      NDN_THROW(Error("Expecting <checker.key-locator.hyper-relation.k-regex>"));
     }
 
     std::string kRegex = hPropertyIt->second.data();
@@ -273,7 +273,7 @@
 
     // Get k-expand
     if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-expand")) {
-      BOOST_THROW_EXCEPTION(Error("Expecting <checker.key-locator.hyper-relation.k-expand>"));
+      NDN_THROW(Error("Expecting <checker.key-locator.hyper-relation.k-expand>"));
     }
 
     std::string kExpand = hPropertyIt->second.data();
@@ -281,7 +281,7 @@
 
     // Get h-relation
     if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "h-relation")) {
-      BOOST_THROW_EXCEPTION(Error("Expecting <checker.key-locator.hyper-relation.h-relation>"));
+      NDN_THROW(Error("Expecting <checker.key-locator.hyper-relation.h-relation>"));
     }
 
     std::string hRelation = hPropertyIt->second.data();
@@ -289,7 +289,7 @@
 
     // Get p-regex
     if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-regex")) {
-      BOOST_THROW_EXCEPTION(Error("Expecting <checker.key-locator.hyper-relation.p-regex>"));
+      NDN_THROW(Error("Expecting <checker.key-locator.hyper-relation.p-regex>"));
     }
 
     std::string pRegex = hPropertyIt->second.data();
@@ -297,14 +297,14 @@
 
     // Get p-expand
     if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-expand")) {
-      BOOST_THROW_EXCEPTION(Error("Expecting <checker.key-locator.hyper-relation.p-expand>"));
+      NDN_THROW(Error("Expecting <checker.key-locator.hyper-relation.p-expand>"));
     }
 
     std::string pExpand = hPropertyIt->second.data();
     hPropertyIt++;
 
     if (hPropertyIt != hSection.end()) {
-      BOOST_THROW_EXCEPTION(Error("Expecting end of <checker.key-locator.hyper-relation>"));
+      NDN_THROW(Error("Expecting end of <checker.key-locator.hyper-relation>"));
     }
 
     NameRelation relation = getNameRelationFromString(hRelation);
@@ -312,11 +312,11 @@
       return make_unique<HyperRelationChecker>(pRegex, pExpand, kRegex, kExpand, relation);
     }
     catch (const Regex::Error&) {
-      BOOST_THROW_EXCEPTION(Error("Invalid regex for <key-locator.hyper-relation>"));
+      NDN_THROW_NESTED(Error("Invalid regex for <key-locator.hyper-relation>"));
     }
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("Unrecognized <checker.key-locator>: " + propertyIt->first));
+    NDN_THROW(Error("Unrecognized <checker.key-locator>: " + propertyIt->first));
   }
 }
 
diff --git a/ndn-cxx/security/v2/validator-config/filter.cpp b/ndn-cxx/security/v2/validator-config/filter.cpp
index f201498..8fa8b2e 100644
--- a/ndn-cxx/security/v2/validator-config/filter.cpp
+++ b/ndn-cxx/security/v2/validator-config/filter.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -78,14 +78,14 @@
   auto propertyIt = configSection.begin();
 
   if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
-    BOOST_THROW_EXCEPTION(Error("Expecting <filter.type>"));
+    NDN_THROW(Error("Expecting <filter.type>"));
   }
 
   std::string type = propertyIt->second.data();
   if (boost::iequals(type, "name"))
     return createNameFilter(configSection, configFilename);
   else
-    BOOST_THROW_EXCEPTION(Error("Unrecognized <filter.type>: " + type));
+    NDN_THROW(Error("Unrecognized <filter.type>: " + type));
 }
 
 unique_ptr<Filter>
@@ -95,7 +95,7 @@
   propertyIt++;
 
   if (propertyIt == configSection.end())
-    BOOST_THROW_EXCEPTION(Error("Unexpected end of <filter>"));
+    NDN_THROW(Error("Unexpected end of <filter>"));
 
   if (boost::iequals(propertyIt->first, "name")) {
     // Get filter.name
@@ -104,21 +104,21 @@
       name = Name(propertyIt->second.data());
     }
     catch (const Name::Error&) {
-      BOOST_THROW_EXCEPTION(Error("Invalid <filter.name>: " + propertyIt->second.data()));
+      NDN_THROW_NESTED(Error("Invalid <filter.name>: " + propertyIt->second.data()));
     }
 
     propertyIt++;
 
     // Get filter.relation
     if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation")) {
-      BOOST_THROW_EXCEPTION(Error("Expecting <filter.relation>"));
+      NDN_THROW(Error("Expecting <filter.relation>"));
     }
 
     NameRelation relation = getNameRelationFromString(propertyIt->second.data());
     propertyIt++;
 
     if (propertyIt != configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expecting end of <filter>"));
+      NDN_THROW(Error("Expecting end of <filter>"));
 
     return make_unique<RelationNameFilter>(name, relation);
   }
@@ -127,17 +127,17 @@
     propertyIt++;
 
     if (propertyIt != configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expecting end of <filter>"));
+      NDN_THROW(Error("Expecting end of <filter>"));
 
     try {
       return make_unique<RegexNameFilter>(Regex(regexString));
     }
     catch (const Regex::Error&) {
-      BOOST_THROW_EXCEPTION(Error("Invalid <filter.regex>: " + regexString));
+      NDN_THROW_NESTED(Error("Invalid <filter.regex>: " + regexString));
     }
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("Unrecognized <filter> property: " + propertyIt->first));
+    NDN_THROW(Error("Unrecognized <filter> property: " + propertyIt->first));
   }
 }
 
diff --git a/ndn-cxx/security/v2/validator-config/name-relation.cpp b/ndn-cxx/security/v2/validator-config/name-relation.cpp
index bd85ed2..ec9991d 100644
--- a/ndn-cxx/security/v2/validator-config/name-relation.cpp
+++ b/ndn-cxx/security/v2/validator-config/name-relation.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -69,7 +69,7 @@
     return NameRelation::IS_STRICT_PREFIX_OF;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("Unsupported relation: " + relationString));
+    NDN_THROW(Error("Unsupported relation: " + relationString));
   }
 }
 
diff --git a/ndn-cxx/security/v2/validator-config/rule.cpp b/ndn-cxx/security/v2/validator-config/rule.cpp
index e4e56cf..f0a5249 100644
--- a/ndn-cxx/security/v2/validator-config/rule.cpp
+++ b/ndn-cxx/security/v2/validator-config/rule.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -54,8 +54,8 @@
 {
   NDN_LOG_TRACE("Trying to match " << pktName);
   if (pktType != m_pktType) {
-    BOOST_THROW_EXCEPTION(Error("Invalid packet type supplied (" +
-                                to_string(pktType) + " != " + to_string(m_pktType) + ")"));
+    NDN_THROW(Error("Invalid packet type supplied (" + to_string(pktType) +
+                    " != " + to_string(m_pktType) + ")"));
   }
 
   if (m_filters.empty()) {
@@ -79,8 +79,8 @@
   NDN_LOG_TRACE("Trying to check " << pktName << " with keyLocator " << klName);
 
   if (pktType != m_pktType) {
-    BOOST_THROW_EXCEPTION(Error("Invalid packet type supplied (" +
-                                to_string(pktType) + " != " + to_string(m_pktType) + ")"));
+    NDN_THROW(Error("Invalid packet type supplied (" + to_string(pktType) +
+                    " != " + to_string(m_pktType) + ")"));
   }
 
   bool hasPendingResult = false;
@@ -102,7 +102,7 @@
 
   // Get rule.id
   if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "id")) {
-    BOOST_THROW_EXCEPTION(Error("Expecting <rule.id>"));
+    NDN_THROW(Error("Expecting <rule.id>"));
   }
 
   std::string ruleId = propertyIt->second.data();
@@ -110,7 +110,7 @@
 
   // Get rule.for
   if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "for")) {
-    BOOST_THROW_EXCEPTION(Error("Expecting <rule.for> in rule: " + ruleId));
+    NDN_THROW(Error("Expecting <rule.for> in rule: " + ruleId));
   }
 
   std::string usage = propertyIt->second.data();
@@ -124,7 +124,7 @@
     isForData = false;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("Unrecognized <rule.for>: " + usage + " in rule: " + ruleId));
+    NDN_THROW(Error("Unrecognized <rule.for>: " + usage + " in rule: " + ruleId));
   }
 
   auto rule = make_unique<Rule>(ruleId, isForData ? tlv::Data : tlv::Interest);
@@ -135,7 +135,7 @@
       if (boost::iequals(propertyIt->first, "checker")) {
         break;
       }
-      BOOST_THROW_EXCEPTION(Error("Expecting <rule.filter> in rule: " + ruleId));
+      NDN_THROW(Error("Expecting <rule.filter> in rule: " + ruleId));
     }
 
     rule->addFilter(Filter::create(propertyIt->second, configFilename));
@@ -145,7 +145,7 @@
   bool hasCheckers = false;
   for (; propertyIt != configSection.end(); propertyIt++) {
     if (!boost::iequals(propertyIt->first, "checker")) {
-      BOOST_THROW_EXCEPTION(Error("Expecting <rule.checker> in rule: " + ruleId));
+      NDN_THROW(Error("Expecting <rule.checker> in rule: " + ruleId));
     }
 
     rule->addChecker(Checker::create(propertyIt->second, configFilename));
@@ -153,11 +153,11 @@
   }
 
   if (propertyIt != configSection.end()) {
-    BOOST_THROW_EXCEPTION(Error("Expecting end of <rule>: " + ruleId));
+    NDN_THROW(Error("Expecting end of <rule>: " + ruleId));
   }
 
   if (!hasCheckers) {
-    BOOST_THROW_EXCEPTION(Error("No <rule.checker> is specified in rule: " + ruleId));
+    NDN_THROW(Error("No <rule.checker> is specified in rule: " + ruleId));
   }
 
   return rule;
diff --git a/ndn-cxx/security/validity-period.cpp b/ndn-cxx/security/validity-period.cpp
index e928634..435056c 100644
--- a/ndn-cxx/security/validity-period.cpp
+++ b/ndn-cxx/security/validity-period.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -96,23 +96,23 @@
 ValidityPeriod::wireDecode(const Block& wire)
 {
   if (!wire.hasWire()) {
-    BOOST_THROW_EXCEPTION(Error("The supplied block does not contain wire format"));
+    NDN_THROW(Error("The supplied block does not contain wire format"));
   }
 
   m_wire = wire;
   m_wire.parse();
 
   if (m_wire.type() != tlv::ValidityPeriod)
-    BOOST_THROW_EXCEPTION(Error("Unexpected TLV type when decoding ValidityPeriod"));
+    NDN_THROW(Error("ValidityPeriod", m_wire.type()));
 
   if (m_wire.elements_size() != 2)
-    BOOST_THROW_EXCEPTION(Error("Does not have two sub-TLVs"));
+    NDN_THROW(Error("ValidityPeriod does not have two sub-TLVs"));
 
   if (m_wire.elements()[NOT_BEFORE_OFFSET].type() != tlv::NotBefore ||
       m_wire.elements()[NOT_BEFORE_OFFSET].value_size() != ISO_DATETIME_SIZE ||
       m_wire.elements()[NOT_AFTER_OFFSET].type() != tlv::NotAfter ||
       m_wire.elements()[NOT_AFTER_OFFSET].value_size() != ISO_DATETIME_SIZE) {
-    BOOST_THROW_EXCEPTION(Error("Invalid NotBefore or NotAfter field"));
+    NDN_THROW(Error("Invalid NotBefore or NotAfter field"));
   }
 
   try {
@@ -122,7 +122,7 @@
                    time::fromIsoString(readString(m_wire.elements()[NOT_AFTER_OFFSET])));
   }
   catch (const std::bad_cast&) {
-    BOOST_THROW_EXCEPTION(Error("Invalid date format in NOT-BEFORE or NOT-AFTER field"));
+    NDN_THROW(Error("Invalid date format in NOT-BEFORE or NOT-AFTER field"));
   }
 }
 
diff --git a/ndn-cxx/selectors.cpp b/ndn-cxx/selectors.cpp
index e1b4722..c972441 100644
--- a/ndn-cxx/selectors.cpp
+++ b/ndn-cxx/selectors.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -131,7 +131,7 @@
 Selectors::wireDecode(const Block& wire)
 {
   if (wire.type() != tlv::Selectors)
-    BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV type when decoding Selectors"));
+    NDN_THROW(tlv::Error("Selectors", wire.type()));
 
   *this = Selectors();
 
@@ -214,7 +214,7 @@
 Selectors::setChildSelector(int childSelector)
 {
   if (childSelector != 0 && childSelector != 1) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("ChildSelector must be 0 or 1"));
+    NDN_THROW(std::invalid_argument("ChildSelector must be 0 or 1"));
   }
   m_childSelector = childSelector;
   m_wire.reset();
diff --git a/ndn-cxx/signature-info.cpp b/ndn-cxx/signature-info.cpp
index fe372c2..41f1cb2 100644
--- a/ndn-cxx/signature-info.cpp
+++ b/ndn-cxx/signature-info.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -61,7 +61,7 @@
 SignatureInfo::wireEncode(EncodingImpl<TAG>& encoder) const
 {
   if (m_type == -1) {
-    BOOST_THROW_EXCEPTION(Error("Cannot encode invalid SignatureInfo"));
+    NDN_THROW(Error("Cannot encode invalid SignatureInfo"));
   }
 
   // SignatureInfo ::= SIGNATURE-INFO-TLV TLV-LENGTH
@@ -116,13 +116,13 @@
   m_wire.parse();
 
   if (m_wire.type() != tlv::SignatureInfo)
-    BOOST_THROW_EXCEPTION(Error("Decoding SignatureInfo, but TLV-TYPE is " + to_string(m_wire.type())));
+    NDN_THROW(Error("SignatureInfo", m_wire.type()));
 
   auto it = m_wire.elements_begin();
 
   // the first sub-element must be SignatureType
   if (it == m_wire.elements_end() || it->type() != tlv::SignatureType)
-    BOOST_THROW_EXCEPTION(Error("Missing SignatureType in SignatureInfo"));
+    NDN_THROW(Error("Missing SignatureType in SignatureInfo"));
 
   m_type = readNonNegativeIntegerAs<tlv::SignatureTypeValue>(*it);
   ++it;
@@ -154,7 +154,7 @@
   if (m_hasKeyLocator)
     return m_keyLocator;
   else
-    BOOST_THROW_EXCEPTION(Error("KeyLocator does not exist in SignatureInfo"));
+    NDN_THROW(Error("KeyLocator does not exist in SignatureInfo"));
 }
 
 void
@@ -177,7 +177,7 @@
 SignatureInfo::getValidityPeriod() const
 {
   if (m_otherTlvs.empty() || m_otherTlvs.front().type() != tlv::ValidityPeriod) {
-    BOOST_THROW_EXCEPTION(Error("ValidityPeriod does not exist in SignatureInfo"));
+    NDN_THROW(Error("ValidityPeriod does not exist in SignatureInfo"));
   }
 
   return security::ValidityPeriod(m_otherTlvs.front());
@@ -207,7 +207,7 @@
       return block;
   }
 
-  BOOST_THROW_EXCEPTION(Error("TLV-TYPE " + to_string(type) + " sub-element does not exist in SignatureInfo"));
+  NDN_THROW(Error("TLV-TYPE " + to_string(type) + " sub-element does not exist in SignatureInfo"));
 }
 
 void
diff --git a/ndn-cxx/signature.cpp b/ndn-cxx/signature.cpp
index c537c60..6c4787c 100644
--- a/ndn-cxx/signature.cpp
+++ b/ndn-cxx/signature.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -44,7 +44,7 @@
 Signature::getType() const
 {
   if (!*this) {
-    BOOST_THROW_EXCEPTION(Error("Signature is invalid"));
+    NDN_THROW(Error("Signature is invalid"));
   }
   return static_cast<tlv::SignatureTypeValue>(m_info.getSignatureType());
 }
@@ -59,7 +59,7 @@
 Signature::setValue(const Block& value)
 {
   if (value.type() != tlv::SignatureValue) {
-    BOOST_THROW_EXCEPTION(Error("Expecting SignatureValue, but TLV-TYPE is " + to_string(value.type())));
+    NDN_THROW(Error("SignatureValue", value.type()));
   }
   m_value = value;
 }
diff --git a/ndn-cxx/transport/detail/stream-transport-impl.hpp b/ndn-cxx/transport/detail/stream-transport-impl.hpp
index dda33e9..944b743 100644
--- a/ndn-cxx/transport/detail/stream-transport-impl.hpp
+++ b/ndn-cxx/transport/detail/stream-transport-impl.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -145,7 +145,7 @@
     else {
       m_transport.m_isConnected = false;
       m_transport.close();
-      BOOST_THROW_EXCEPTION(Transport::Error(error, "error while connecting to the forwarder"));
+      NDN_THROW(Transport::Error(error, "error while connecting to the forwarder"));
     }
   }
 
@@ -156,7 +156,7 @@
       return;
 
     m_transport.close();
-    BOOST_THROW_EXCEPTION(Transport::Error(error, "error while connecting to the forwarder"));
+    NDN_THROW(Transport::Error(error, "error while connecting to the forwarder"));
   }
 
   void
@@ -190,7 +190,7 @@
       }
 
       m_transport.close();
-      BOOST_THROW_EXCEPTION(Transport::Error(error, "error while sending data to socket"));
+      NDN_THROW(Transport::Error(error, "error while sending data to socket"));
     }
 
     if (!m_transport.m_isConnected) {
@@ -222,7 +222,7 @@
       }
 
       m_transport.close();
-      BOOST_THROW_EXCEPTION(Transport::Error(error, "error while receiving data from socket"));
+      NDN_THROW(Transport::Error(error, "error while receiving data from socket"));
     }
 
     m_inputBufferSize += nBytesRecvd;
@@ -232,9 +232,8 @@
     bool hasProcessedSome = processAllReceived(m_inputBuffer, offset, m_inputBufferSize);
     if (!hasProcessedSome && m_inputBufferSize == MAX_NDN_PACKET_SIZE && offset == 0) {
       m_transport.close();
-      BOOST_THROW_EXCEPTION(Transport::Error(boost::system::error_code(),
-                                             "input buffer full, but a valid TLV cannot be "
-                                             "decoded"));
+      NDN_THROW(Transport::Error(boost::system::error_code(),
+                                 "input buffer full, but a valid TLV cannot be decoded"));
     }
 
     if (offset > 0) {
diff --git a/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp b/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp
index 6ca3b1e..986eb57 100644
--- a/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp
+++ b/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -69,13 +69,13 @@
       if (error == boost::system::errc::operation_canceled)
         return;
 
-      BOOST_THROW_EXCEPTION(Transport::Error(error, "Error during resolution of host or port"));
+      NDN_THROW(Transport::Error(error, "Error during resolution of host or port"));
     }
 
     typename Protocol::resolver::iterator end;
     if (endpoint == end) {
       this->m_transport.close();
-      BOOST_THROW_EXCEPTION(Transport::Error(error, "Unable to resolve host or port"));
+      NDN_THROW(Transport::Error(error, "Unable to resolve host or port"));
     }
 
     this->m_socket.async_connect(*endpoint, bind(&Impl::connectHandler, this->shared_from_this(), _1));
diff --git a/ndn-cxx/transport/tcp-transport.cpp b/ndn-cxx/transport/tcp-transport.cpp
index 30a5087..0b78b19 100644
--- a/ndn-cxx/transport/tcp-transport.cpp
+++ b/ndn-cxx/transport/tcp-transport.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -59,7 +59,7 @@
 
     const std::string scheme = uri.getScheme();
     if (scheme != "tcp" && scheme != "tcp4" && scheme != "tcp6") {
-      BOOST_THROW_EXCEPTION(Error("Cannot create TcpTransport from \"" + scheme + "\" URI"));
+      NDN_THROW(Error("Cannot create TcpTransport from \"" + scheme + "\" URI"));
     }
 
     if (!uri.getHost().empty()) {
@@ -71,7 +71,7 @@
     }
   }
   catch (const FaceUri::Error& error) {
-    BOOST_THROW_EXCEPTION(Error(error.what()));
+    NDN_THROW_NESTED(Error(error.what()));
   }
 
   return {host, port};
diff --git a/ndn-cxx/transport/transport.cpp b/ndn-cxx/transport/transport.cpp
index b6dac08..23895b0 100644
--- a/ndn-cxx/transport/transport.cpp
+++ b/ndn-cxx/transport/transport.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -28,11 +28,6 @@
 {
 }
 
-Transport::Error::Error(const std::string& msg)
-  : std::runtime_error(msg)
-{
-}
-
 Transport::Transport()
   : m_ioService(nullptr)
   , m_isConnected(false)
diff --git a/ndn-cxx/transport/transport.hpp b/ndn-cxx/transport/transport.hpp
index daede21..6954686 100644
--- a/ndn-cxx/transport/transport.hpp
+++ b/ndn-cxx/transport/transport.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -38,10 +38,9 @@
   class Error : public std::runtime_error
   {
   public:
-    Error(const boost::system::error_code& code, const std::string& msg);
+    using std::runtime_error::runtime_error;
 
-    explicit
-    Error(const std::string& msg);
+    Error(const boost::system::error_code& code, const std::string& msg);
   };
 
   typedef function<void(const Block& wire)> ReceiveCallback;
diff --git a/ndn-cxx/transport/unix-transport.cpp b/ndn-cxx/transport/unix-transport.cpp
index d444e35..b33704c 100644
--- a/ndn-cxx/transport/unix-transport.cpp
+++ b/ndn-cxx/transport/unix-transport.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -52,8 +52,7 @@
     const FaceUri uri(uriString);
 
     if (uri.getScheme() != "unix") {
-      BOOST_THROW_EXCEPTION(Error("Cannot create UnixTransport from \"" +
-                                  uri.getScheme() + "\" URI"));
+      NDN_THROW(Error("Cannot create UnixTransport from \"" + uri.getScheme() + "\" URI"));
     }
 
     if (!uri.getPath().empty()) {
@@ -61,7 +60,7 @@
     }
   }
   catch (const FaceUri::Error& error) {
-    BOOST_THROW_EXCEPTION(Error(error.what()));
+    NDN_THROW_NESTED(Error(error.what()));
   }
 
   return path;
diff --git a/ndn-cxx/util/config-file.cpp b/ndn-cxx/util/config-file.cpp
index b057ded..f08d3eb 100644
--- a/ndn-cxx/util/config-file.cpp
+++ b/ndn-cxx/util/config-file.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -105,21 +105,18 @@
 ConfigFile::parse()
 {
   if (m_path.empty()) {
-    BOOST_THROW_EXCEPTION(Error("Failed to locate configuration file for parsing"));
+    NDN_THROW(Error("Failed to locate configuration file for parsing"));
   }
   if (!m_input.is_open() && !open()) {
-    BOOST_THROW_EXCEPTION(Error("Failed to open configuration file for parsing"));
+    NDN_THROW(Error("Failed to open configuration file for parsing"));
   }
 
   try {
     boost::property_tree::read_ini(m_input, m_config);
   }
   catch (const boost::property_tree::ini_parser_error& error) {
-    std::ostringstream msg;
-    msg << "Failed to parse configuration file";
-    msg << " " << m_path;
-    msg << " " << error.message() << " line " << error.line();
-    BOOST_THROW_EXCEPTION(Error(msg.str()));
+    NDN_THROW(Error("Failed to parse configuration file " + error.filename() +
+                    " line " + to_string(error.line()) + ": " + error.message()));
   }
   return m_config;
 }
diff --git a/ndn-cxx/util/dummy-client-face.cpp b/ndn-cxx/util/dummy-client-face.cpp
index 6629757..9f2cb9e 100644
--- a/ndn-cxx/util/dummy-client-face.cpp
+++ b/ndn-cxx/util/dummy-client-face.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -292,7 +292,7 @@
   if (m_bcastLink != nullptr && other.m_bcastLink != nullptr) {
     if (m_bcastLink != other.m_bcastLink) {
       // already on different links
-      BOOST_THROW_EXCEPTION(AlreadyLinkedError());
+      NDN_THROW(AlreadyLinkedError());
     }
   }
   else if (m_bcastLink == nullptr && other.m_bcastLink != nullptr) {
diff --git a/ndn-cxx/util/io.cpp b/ndn-cxx/util/io.cpp
index 6f8484e..ac9f2b7 100644
--- a/ndn-cxx/util/io.cpp
+++ b/ndn-cxx/util/io.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -79,11 +79,11 @@
         t::bufferSource(block.wire(), block.size()) >> t::hexEncode(true) >> t::streamSink(os);
         break;
       default:
-        BOOST_THROW_EXCEPTION(Error("unrecognized IoEncoding"));
+        NDN_THROW(Error("Unknown IoEncoding " + to_string(encoding)));
     }
   }
-  catch (const t::Error& e) {
-    BOOST_THROW_EXCEPTION(Error(e.what()));
+  catch (const t::Error&) {
+    NDN_THROW_NESTED(Error("Transform error during save"));
   }
 }
 
diff --git a/ndn-cxx/util/io.hpp b/ndn-cxx/util/io.hpp
index 9b2d04a..e8f6e8d 100644
--- a/ndn-cxx/util/io.hpp
+++ b/ndn-cxx/util/io.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -140,8 +140,8 @@
   try {
     block = obj.wireEncode();
   }
-  catch (const tlv::Error& e) {
-    BOOST_THROW_EXCEPTION(Error(e.what()));
+  catch (const tlv::Error&) {
+    NDN_THROW_NESTED(Error("Encode error during save"));
   }
 
   saveBlock(block, os, encoding);
diff --git a/ndn-cxx/util/logger.cpp b/ndn-cxx/util/logger.cpp
index b8a0b43..5f6c2de 100644
--- a/ndn-cxx/util/logger.cpp
+++ b/ndn-cxx/util/logger.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -53,7 +53,7 @@
     return os << "ALL";
   }
 
-  BOOST_THROW_EXCEPTION(std::invalid_argument("unknown log level " + to_string(static_cast<int>(level))));
+  NDN_THROW(std::invalid_argument("unknown log level " + to_string(static_cast<int>(level))));
 }
 
 LogLevel
@@ -76,7 +76,7 @@
   else if (s == "ALL")
     return LogLevel::ALL;
 
-  BOOST_THROW_EXCEPTION(std::invalid_argument("unrecognized log level '" + s + "'"));
+  NDN_THROW(std::invalid_argument("unrecognized log level '" + s + "'"));
 }
 
 /**
@@ -104,7 +104,7 @@
   : m_moduleName(name)
 {
   if (!isValidLoggerName(m_moduleName)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Logger name '" + m_moduleName + "' is invalid"));
+    NDN_THROW(std::invalid_argument("Logger name '" + m_moduleName + "' is invalid"));
   }
   this->setLevel(LogLevel::NONE);
   Logging::get().addLoggerImpl(*this);
@@ -115,7 +115,7 @@
 {
   std::string moduleName(name);
   if (!isValidLoggerName(moduleName)) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("Logger name '" + moduleName + "' is invalid"));
+    NDN_THROW(std::invalid_argument("Logger name '" + moduleName + "' is invalid"));
   }
   Logging::get().registerLoggerNameImpl(std::move(moduleName));
 }
diff --git a/ndn-cxx/util/logging.cpp b/ndn-cxx/util/logging.cpp
index e913c15..5f19548 100644
--- a/ndn-cxx/util/logging.cpp
+++ b/ndn-cxx/util/logging.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -181,7 +181,7 @@
   while (std::getline(ss, configModule, ':')) {
     size_t ind = configModule.find('=');
     if (ind == std::string::npos) {
-      BOOST_THROW_EXCEPTION(std::invalid_argument("malformed logging config: '=' is missing"));
+      NDN_THROW(std::invalid_argument("malformed logging config: '=' is missing"));
     }
 
     std::string moduleName = configModule.substr(0, ind);
diff --git a/ndn-cxx/util/random.cpp b/ndn-cxx/util/random.cpp
index 92a5f32..5ff643e 100644
--- a/ndn-cxx/util/random.cpp
+++ b/ndn-cxx/util/random.cpp
@@ -45,8 +45,8 @@
 generateSecureBytes(uint8_t* bytes, size_t size)
 {
   if (RAND_bytes(bytes, size) != 1) {
-    BOOST_THROW_EXCEPTION(std::runtime_error("Failed to generate random bytes (error code " +
-                                             to_string(ERR_get_error()) + ")"));
+    NDN_THROW(std::runtime_error("Failed to generate random bytes (error code " +
+                                 to_string(ERR_get_error()) + ")"));
   }
 }
 
diff --git a/ndn-cxx/util/regex/regex-backref-matcher.cpp b/ndn-cxx/util/regex/regex-backref-matcher.cpp
index 0a95c32..0b531ce 100644
--- a/ndn-cxx/util/regex/regex-backref-matcher.cpp
+++ b/ndn-cxx/util/regex/regex-backref-matcher.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -36,7 +36,7 @@
 RegexBackrefMatcher::compile()
 {
   if (m_expr.size() < 2)
-    BOOST_THROW_EXCEPTION(Error("Unrecognized format: " + m_expr));
+    NDN_THROW(Error("Unrecognized format: " + m_expr));
 
   size_t lastIndex = m_expr.size() - 1;
   if ('(' == m_expr[0] && ')' == m_expr[lastIndex]) {
@@ -44,7 +44,7 @@
                                                               m_backrefManager));
   }
   else
-    BOOST_THROW_EXCEPTION(Error("Unrecognized format: " + m_expr));
+    NDN_THROW(Error("Unrecognized format: " + m_expr));
 }
 
 } // namespace ndn
diff --git a/ndn-cxx/util/regex/regex-component-matcher.cpp b/ndn-cxx/util/regex/regex-component-matcher.cpp
index 037710d..604c0ee 100644
--- a/ndn-cxx/util/regex/regex-component-matcher.cpp
+++ b/ndn-cxx/util/regex/regex-component-matcher.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -60,7 +60,7 @@
   }
 
   if (!m_isExactMatch)
-    BOOST_THROW_EXCEPTION(Error("Non-exact component search is not supported yet"));
+    NDN_THROW(Error("Non-exact component search is not supported yet"));
 
   std::smatch subResult;
   std::string targetStr = name.get(offset).toUri();
diff --git a/ndn-cxx/util/regex/regex-component-set-matcher.cpp b/ndn-cxx/util/regex/regex-component-set-matcher.cpp
index a1b0747..6c2eca8 100644
--- a/ndn-cxx/util/regex/regex-component-set-matcher.cpp
+++ b/ndn-cxx/util/regex/regex-component-set-matcher.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -38,7 +38,7 @@
 RegexComponentSetMatcher::compile()
 {
   if (m_expr.size() < 2)
-    BOOST_THROW_EXCEPTION(Error("Regexp compile error (cannot parse " + m_expr + ")"));
+    NDN_THROW(Error("Regexp compile error (cannot parse " + m_expr + ")"));
 
   switch (m_expr[0]) {
     case '<':
@@ -46,7 +46,7 @@
     case '[': {
       size_t lastIndex = m_expr.size() - 1;
       if (']' != m_expr[lastIndex])
-        BOOST_THROW_EXCEPTION(Error("Regexp compile error (no matching ']' in " + m_expr + ")"));
+        NDN_THROW(Error("Regexp compile error (no matching ']' in " + m_expr + ")"));
 
       if ('^' == m_expr[1]) {
         m_isInclusion = false;
@@ -57,7 +57,7 @@
       break;
     }
     default:
-      BOOST_THROW_EXCEPTION(Error("Regexp compile error (cannot parse " + m_expr + ")"));
+      NDN_THROW(Error("Regexp compile error (cannot parse " + m_expr + ")"));
   }
 }
 
@@ -66,7 +66,7 @@
 {
   size_t end = extractComponent(1);
   if (m_expr.size() != end)
-    BOOST_THROW_EXCEPTION(Error("Component expr error " + m_expr));
+    NDN_THROW(Error("Component expr error " + m_expr));
 
   m_components.push_back(make_shared<RegexComponentMatcher>(m_expr.substr(1, end - 2), m_backrefManager));
 }
@@ -79,7 +79,7 @@
 
   while (index < lastIndex) {
     if ('<' != m_expr[index])
-      BOOST_THROW_EXCEPTION(Error("Component expr error " + m_expr));
+      NDN_THROW(Error("Component expr error " + m_expr));
 
     tempIndex = index + 1;
     index = extractComponent(tempIndex);
@@ -88,7 +88,7 @@
   }
 
   if (index != lastIndex)
-    BOOST_THROW_EXCEPTION(Error("Not sufficient expr to parse " + m_expr));
+    NDN_THROW(Error("Not sufficient expr to parse " + m_expr));
 }
 
 bool
@@ -131,7 +131,7 @@
         rcount++;
         break;
       case 0:
-        BOOST_THROW_EXCEPTION(Error("Square brackets mismatch"));
+        NDN_THROW(Error("Square brackets mismatch"));
         break;
     }
     index++;
diff --git a/ndn-cxx/util/regex/regex-pattern-list-matcher.cpp b/ndn-cxx/util/regex/regex-pattern-list-matcher.cpp
index 1923875..a0464c3 100644
--- a/ndn-cxx/util/regex/regex-pattern-list-matcher.cpp
+++ b/ndn-cxx/util/regex/regex-pattern-list-matcher.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -45,7 +45,7 @@
     subHead = index;
 
     if (!extractPattern(subHead, &index))
-      BOOST_THROW_EXCEPTION(Error("Compile error"));
+      NDN_THROW(Error("Compile error"));
   }
 }
 
@@ -93,7 +93,7 @@
     break;
 
   default:
-    BOOST_THROW_EXCEPTION(Error("Unexpected syntax"));
+    NDN_THROW(Error("Unexpected character "s + m_expr[index]));
   }
 
   *next = end;
@@ -108,7 +108,7 @@
 
   while (lcount > rcount) {
     if (index >= m_expr.size())
-      BOOST_THROW_EXCEPTION(Error("Parenthesis mismatch"));
+      NDN_THROW(Error("Parenthesis mismatch"));
 
     if (left == m_expr[index])
       lcount++;
@@ -141,7 +141,7 @@
         break;
     }
     if (index == exprSize)
-      BOOST_THROW_EXCEPTION(Error("Missing right brace bracket"));
+      NDN_THROW(Error("Missing closing brace"));
     else
       return ++index;
   }
diff --git a/ndn-cxx/util/regex/regex-repeat-matcher.cpp b/ndn-cxx/util/regex/regex-repeat-matcher.cpp
index 882991a..159dc41 100644
--- a/ndn-cxx/util/regex/regex-repeat-matcher.cpp
+++ b/ndn-cxx/util/regex/regex-repeat-matcher.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -111,10 +111,10 @@
       max = min;
     }
     else
-      BOOST_THROW_EXCEPTION(Error("RegexRepeatMatcher::parseRepetition(): Unrecognized format " + m_expr));
+      NDN_THROW(Error("parseRepetition: unrecognized format " + m_expr));
 
     if (min > MAX_REPETITIONS || max > MAX_REPETITIONS || min > max)
-      BOOST_THROW_EXCEPTION(Error("RegexRepeatMatcher::parseRepetition(): Wrong number " + m_expr));
+      NDN_THROW(Error("parseRepetition: wrong number " + m_expr));
 
     m_repeatMin = min;
     m_repeatMax = max;
diff --git a/ndn-cxx/util/regex/regex-top-matcher.cpp b/ndn-cxx/util/regex/regex-top-matcher.cpp
index e2c4209..f326ca5 100644
--- a/ndn-cxx/util/regex/regex-top-matcher.cpp
+++ b/ndn-cxx/util/regex/regex-top-matcher.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -118,7 +118,7 @@
           result.append(i);
       }
       else
-        BOOST_THROW_EXCEPTION(Error("Exceed the range of back reference"));
+        NDN_THROW(Error("Exceeded the range of back reference"));
     }
   }
 
@@ -133,22 +133,22 @@
   if (expand[offset] == '\\') {
     offset++;
     if (offset >= expand.size())
-      BOOST_THROW_EXCEPTION(Error("Wrong format of expand string"));
+      NDN_THROW(Error("Wrong format of expand string"));
 
     while (expand[offset] <= '9' and expand[offset] >= '0') {
       offset++;
       if (offset > expand.size())
-        BOOST_THROW_EXCEPTION(Error("Wrong format of expand string"));
+        NDN_THROW(Error("Wrong format of expand string"));
     }
     if (offset > begin + 1)
       return expand.substr(begin, offset - begin);
     else
-      BOOST_THROW_EXCEPTION(Error("Wrong format of expand string"));
+      NDN_THROW(Error("Wrong format of expand string"));
   }
   else if (expand[offset] == '<') {
     offset++;
     if (offset >= expand.size())
-      BOOST_THROW_EXCEPTION(Error("Wrong format of expand string"));
+      NDN_THROW(Error("Wrong format of expand string"));
 
     size_t left = 1;
     size_t right = 0;
@@ -159,12 +159,12 @@
         right++;
       offset++;
       if (offset >= expand.size())
-        BOOST_THROW_EXCEPTION(Error("Wrong format of expand string"));
+        NDN_THROW(Error("Wrong format of expand string"));
     }
     return expand.substr(begin, offset - begin);
   }
   else
-    BOOST_THROW_EXCEPTION(Error("Wrong format of expand string"));
+    NDN_THROW(Error("Wrong format of expand string"));
 }
 
 shared_ptr<RegexTopMatcher>
diff --git a/ndn-cxx/util/segment-fetcher.cpp b/ndn-cxx/util/segment-fetcher.cpp
index 2d70aee..09cfd4e 100644
--- a/ndn-cxx/util/segment-fetcher.cpp
+++ b/ndn-cxx/util/segment-fetcher.cpp
@@ -1,8 +1,8 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
+ * Copyright (c) 2013-2019 Regents of the University of California,
+ *                         Colorado State University,
+ *                         University Pierre & Marie Curie, Sorbonne University.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -46,19 +46,19 @@
 SegmentFetcher::Options::validate()
 {
   if (maxTimeout < 1_ms) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("maxTimeout must be greater than or equal to 1 millisecond"));
+    NDN_THROW(std::invalid_argument("maxTimeout must be greater than or equal to 1 millisecond"));
   }
 
   if (initCwnd < 1.0) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("initCwnd must be greater than or equal to 1"));
+    NDN_THROW(std::invalid_argument("initCwnd must be greater than or equal to 1"));
   }
 
   if (aiStep < 0.0) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("aiStep must be greater than or equal to 0"));
+    NDN_THROW(std::invalid_argument("aiStep must be greater than or equal to 0"));
   }
 
   if (mdCoef < 0.0 || mdCoef > 1.0) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("mdCoef must be in range [0, 1]"));
+    NDN_THROW(std::invalid_argument("mdCoef must be in range [0, 1]"));
   }
 }
 
diff --git a/ndn-cxx/util/segment-fetcher.hpp b/ndn-cxx/util/segment-fetcher.hpp
index 9a3d5fd..9b7f5bb 100644
--- a/ndn-cxx/util/segment-fetcher.hpp
+++ b/ndn-cxx/util/segment-fetcher.hpp
@@ -1,8 +1,8 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
+ * Copyright (c) 2013-2019 Regents of the University of California,
+ *                         Colorado State University,
+ *                         University Pierre & Marie Curie, Sorbonne University.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
diff --git a/ndn-cxx/util/sha256.cpp b/ndn-cxx/util/sha256.cpp
index 6580114..3575884 100644
--- a/ndn-cxx/util/sha256.cpp
+++ b/ndn-cxx/util/sha256.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -118,7 +118,7 @@
 Sha256::update(const uint8_t* buffer, size_t size)
 {
   if (m_isFinalized)
-    BOOST_THROW_EXCEPTION(Error("Digest has been already finalized"));
+    NDN_THROW(Error("Digest has been already finalized"));
 
   BOOST_ASSERT(m_input != nullptr);
   m_input->write(buffer, size);
diff --git a/ndn-cxx/util/sqlite3-statement.cpp b/ndn-cxx/util/sqlite3-statement.cpp
index 1b2e9eb..4426a02 100644
--- a/ndn-cxx/util/sqlite3-statement.cpp
+++ b/ndn-cxx/util/sqlite3-statement.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -35,7 +35,7 @@
 {
   int res = sqlite3_prepare_v2(database, statement.data(), -1, &m_stmt, nullptr);
   if (res != SQLITE_OK)
-    BOOST_THROW_EXCEPTION(std::domain_error("bad SQL statement: " + statement));
+    NDN_THROW(std::domain_error("bad SQL statement: " + statement));
 }
 
 int
diff --git a/ndn-cxx/util/string-helper.cpp b/ndn-cxx/util/string-helper.cpp
index 184458d..06b08a6 100644
--- a/ndn-cxx/util/string-helper.cpp
+++ b/ndn-cxx/util/string-helper.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -87,7 +87,7 @@
     tr::bufferSource(hexString) >> tr::hexDecode() >> tr::streamSink(os);
   }
   catch (const tr::Error& e) {
-    BOOST_THROW_EXCEPTION(StringHelperError("Conversion from hex failed: "s + e.what()));
+    NDN_THROW_NESTED(StringHelperError("Conversion from hex failed: "s + e.what()));
   }
 
   return os.buf();
diff --git a/ndn-cxx/util/string-helper.hpp b/ndn-cxx/util/string-helper.hpp
index 59638cb..57c27fb 100644
--- a/ndn-cxx/util/string-helper.hpp
+++ b/ndn-cxx/util/string-helper.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -31,11 +31,7 @@
 class StringHelperError : public std::invalid_argument
 {
 public:
-  explicit
-  StringHelperError(const std::string& what)
-    : std::invalid_argument(what)
-  {
-  }
+  using std::invalid_argument::invalid_argument;
 };
 
 /**
diff --git a/tests/unit/lp/packet.t.cpp b/tests/unit/lp/packet.t.cpp
index a8b5819..30c8bae 100644
--- a/tests/unit/lp/packet.t.cpp
+++ b/tests/unit/lp/packet.t.cpp
@@ -44,7 +44,7 @@
   packet.set<FragIndexField>(1234);
   BOOST_CHECK(!packet.empty());
   BOOST_CHECK(packet.has<FragIndexField>());
-  BOOST_CHECK_THROW(packet.add<FragIndexField>(5678), std::length_error);
+  BOOST_CHECK_THROW(packet.add<FragIndexField>(5678), std::invalid_argument);
   BOOST_CHECK_EQUAL(packet.count<FragIndexField>(), 1);
   BOOST_CHECK_EQUAL(packet.get<FragIndexField>(0), 1234);
   BOOST_CHECK_THROW(packet.get<FragIndexField>(1), std::out_of_range);
diff --git a/tests/unit/mgmt/dispatcher.t.cpp b/tests/unit/mgmt/dispatcher.t.cpp
index c24f9cf..7fa74e5 100644
--- a/tests/unit/mgmt/dispatcher.t.cpp
+++ b/tests/unit/mgmt/dispatcher.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -68,7 +68,7 @@
   wireDecode(const Block& wire) final
   {
     if (wire.type() != 128)
-      BOOST_THROW_EXCEPTION(tlv::Error("Expecting TLV type 128"));
+      NDN_THROW(tlv::Error("Expecting TLV type 128"));
   }
 };
 
diff --git a/tests/unit/util/io.t.cpp b/tests/unit/util/io.t.cpp
index 052e149..f8595c9 100644
--- a/tests/unit/util/io.t.cpp
+++ b/tests/unit/util/io.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -93,7 +93,7 @@
   wireEncode() const
   {
     if (shouldThrow) {
-      BOOST_THROW_EXCEPTION(tlv::Error("encode error"));
+      NDN_THROW(tlv::Error("encode error"));
     }
 
     // block will be 0xAA, 0x01, 0xDD
@@ -120,7 +120,7 @@
   wireDecode(const Block& block)
   {
     if (m_shouldThrow) {
-      BOOST_THROW_EXCEPTION(tlv::Error("decode error"));
+      NDN_THROW(tlv::Error("decode error"));
     }
 
     // block must be 0xBB, 0x01, 0xEE
diff --git a/tests/unit/util/scheduler.t.cpp b/tests/unit/util/scheduler.t.cpp
index 49c90b6..d8335c4 100644
--- a/tests/unit/util/scheduler.t.cpp
+++ b/tests/unit/util/scheduler.t.cpp
@@ -85,7 +85,12 @@
   class MyException : public std::exception
   {
   };
-  scheduler.scheduleEvent(10_ms, [] { BOOST_THROW_EXCEPTION(MyException()); });
+  scheduler.scheduleEvent(10_ms, [] {
+    // use plain 'throw' to ensure that Scheduler does not depend on the
+    // internal machinery of NDN_THROW and that it can catch all exceptions
+    // regardless of how they are thrown by the application
+    throw MyException{};
+  });
 
   bool isCallbackInvoked = false;
   scheduler.scheduleEvent(20_ms, [&isCallbackInvoked] { isCallbackInvoked = true; });
diff --git a/tests/unit/util/signal.t.cpp b/tests/unit/util/signal.t.cpp
index de22534..f0eb192 100644
--- a/tests/unit/util/signal.t.cpp
+++ b/tests/unit/util/signal.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -424,14 +424,17 @@
 {
   SignalOwner0 so;
 
-  struct HandlerError : public std::exception
+  class HandlerError : public std::exception
   {
   };
 
   int hit = 0;
   so.sig.connect([&] {
     ++hit;
-    BOOST_THROW_EXCEPTION(HandlerError());
+    // use plain 'throw' to ensure that Signal does not depend on the internal
+    // machinery of NDN_THROW and that it can catch all exceptions regardless
+    // of how they are thrown by the application
+    throw HandlerError{};
   });
 
   BOOST_CHECK_THROW(so.emitSignal(sig), HandlerError);
diff --git a/tests/unit/util/simple-notification.hpp b/tests/unit/util/simple-notification.hpp
index ac81f5f..431b8c2 100644
--- a/tests/unit/util/simple-notification.hpp
+++ b/tests/unit/util/simple-notification.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018 Regents of the University of California,
+ * Copyright (c) 2014-2019 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -68,7 +68,7 @@
 
     // error for testing
     if (!m_message.empty() && m_message[0] == '\x07')
-      BOOST_THROW_EXCEPTION(tlv::Error("0x07 error"));
+      NDN_THROW(tlv::Error("0x07 error"));
   }
 
   const std::string&
diff --git a/tests/unit/util/time.t.cpp b/tests/unit/util/time.t.cpp
index 6ed55d5..3f5f531 100644
--- a/tests/unit/util/time.t.cpp
+++ b/tests/unit/util/time.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -23,6 +23,7 @@
 
 #include "tests/boost-test.hpp"
 
+#include <boost/lexical_cast.hpp>
 #include <thread>
 
 namespace ndn {
@@ -125,8 +126,10 @@
   auto year2042 = fromIsoString("20420101T000001.042000");
   auto year2010 = fromIsoString("20100101T000001.042000");
 
-  BOOST_CHECK_EQUAL(to_string(year2010), "1262304001042000000 nanoseconds since Jan 1, 1970");
-  BOOST_CHECK_EQUAL(to_string(year2042), "2272147201042000000 nanoseconds since Jan 1, 1970");
+  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(year2010),
+                    "1262304001042000000 nanoseconds since Jan 1, 1970");
+  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(year2042),
+                    "2272147201042000000 nanoseconds since Jan 1, 1970");
   BOOST_CHECK_GT(year2042, year2010);
 }
 
diff --git a/tools/ndnsec/cert-install.cpp b/tools/ndnsec/cert-install.cpp
index 3ae6724..7bf17a0 100644
--- a/tools/ndnsec/cert-install.cpp
+++ b/tools/ndnsec/cert-install.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -51,7 +51,7 @@
 
   requestStream.connect(host, port);
   if (!requestStream) {
-    BOOST_THROW_EXCEPTION(HttpException("HTTP connection error"));
+    NDN_THROW(HttpException("HTTP connection error"));
   }
 
   requestStream << "GET " << path << " HTTP/1.0\r\n";
@@ -64,7 +64,7 @@
   std::string statusLine;
   std::getline(requestStream, statusLine);
   if (!requestStream) {
-    BOOST_THROW_EXCEPTION(HttpException("HTTP communication error"));
+    NDN_THROW(HttpException("HTTP communication error"));
   }
 
   std::stringstream responseStream(statusLine);
@@ -76,10 +76,10 @@
 
   std::getline(responseStream, statusMessage);
   if (!requestStream || httpVersion.substr(0, 5) != "HTTP/") {
-    BOOST_THROW_EXCEPTION(HttpException("HTTP communication error"));
+    NDN_THROW(HttpException("HTTP communication error"));
   }
   if (statusCode != 200) {
-    BOOST_THROW_EXCEPTION(HttpException("HTTP server error"));
+    NDN_THROW(HttpException("HTTP server error"));
   }
   std::string header;
   while (std::getline(requestStream, header) && header != "\r")
@@ -152,38 +152,37 @@
   }
 
   security::v2::Certificate cert;
-
   try {
-  if (certFileName.find("http://") == 0) {
-    std::string host;
-    std::string port;
-    std::string path;
+    if (certFileName.find("http://") == 0) {
+      std::string host;
+      std::string port;
+      std::string path;
 
-    size_t pos = 7; // offset of "http://"
-    size_t posSlash = certFileName.find("/", pos);
+      size_t pos = 7; // offset of "http://"
+      size_t posSlash = certFileName.find("/", pos);
 
-    if (posSlash == std::string::npos)
-      BOOST_THROW_EXCEPTION(HttpException("Request line is not correctly formatted"));
+      if (posSlash == std::string::npos)
+        NDN_THROW(HttpException("Request line is not correctly formatted"));
 
-    size_t posPort = certFileName.find(":", pos);
+      size_t posPort = certFileName.find(":", pos);
 
-    if (posPort != std::string::npos && posPort < posSlash) {
-      // port is specified
-      port = certFileName.substr(posPort + 1, posSlash - posPort - 1);
-      host = certFileName.substr(pos, posPort - pos);
+      if (posPort != std::string::npos && posPort < posSlash) {
+        // port is specified
+        port = certFileName.substr(posPort + 1, posSlash - posPort - 1);
+        host = certFileName.substr(pos, posPort - pos);
+      }
+      else {
+        port = "80";
+        host = certFileName.substr(pos, posSlash - pos);
+      }
+
+      path = certFileName.substr(posSlash, certFileName.size() - posSlash);
+
+      cert = getCertificateHttp(host, port, path);
     }
     else {
-      port = "80";
-      host = certFileName.substr(pos, posSlash - pos);
+      cert = loadCertificate(certFileName);
     }
-
-    path = certFileName.substr(posSlash, certFileName.size() - posSlash);
-
-    cert = getCertificateHttp(host, port, path);
-  }
-  else {
-    cert = loadCertificate(certFileName);
-  }
   }
   catch (const CannotLoadCertificate&) {
     std::cerr << "ERROR: Cannot load the certificate " << certFileName << std::endl;
diff --git a/tools/ndnsec/util.cpp b/tools/ndnsec/util.cpp
index 5e5c341..1a4b8f4 100644
--- a/tools/ndnsec/util.cpp
+++ b/tools/ndnsec/util.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -75,7 +75,7 @@
     cert = io::load<security::v2::Certificate>(fileName);
 
   if (cert == nullptr) {
-    BOOST_THROW_EXCEPTION(CannotLoadCertificate(fileName));
+    NDN_THROW(CannotLoadCertificate(fileName));
   }
   return *cert;
 }