fix exceptionStr to work for derived classes of std::exception
authorMarc Horowitz <mhorowitz@fb.com>
Thu, 4 Sep 2014 02:32:36 +0000 (19:32 -0700)
committerSara Golemon <sgolemon@fb.com>
Tue, 9 Sep 2014 21:22:23 +0000 (14:22 -0700)
Summary:
templates and overloads are hard.  This uses SFINAE to get
the desired behavior, and includes a test.

This also removes a hack in ExceptionWrapper which isn't needed with this fix.

Test Plan: string_test, exception_wrapper_test

Reviewed By: andrei.alexandrescu@fb.com

Subscribers: dreiss, dancol, njormrod

FB internal diff: D1535681

Blame Revision: D1517701

folly/ExceptionWrapper.h
folly/String.h
folly/test/StringTest.cpp

index 14f2b71bcf70bbf4a118e84879c9c053e5f8d796..080822323b19003d73260d8632d122abb551491c 100644 (file)
@@ -275,8 +275,7 @@ class try_and_catch<LastException, Exceptions...> :
   typename std::enable_if<std::is_base_of<std::exception, Ex>::value>::type
   assign_eptr(Ex& e) {
     this->eptr_ = std::current_exception();
-    // The cast is needed so we get the desired overload of exceptionStr()
-    this->estr_ = exceptionStr(static_cast<std::exception&>(e)).toStdString();
+    this->estr_ = exceptionStr(e).toStdString();
   }
 
   template <typename Ex>
index 223c49073ca6be1278a67cde04d565921c0258c4..14fda430918e3af6314c5ddeeb6071f342dc1b09 100644 (file)
@@ -349,15 +349,9 @@ std::string hexDump(const void* ptr, size_t size);
 fbstring errnoStr(int err);
 
 /**
- * Debug string for an exception: include type and what().  Note that
- * the non-templated function overloads will be used in preference to
- * the template.
+ * Debug string for an exception: include type and what(), if
+ * defined.
  */
-template<typename T>
-fbstring exceptionStr(const T& e) {
-  return folly::to<fbstring>(demangle(typeid(e)));
-}
-
 inline fbstring exceptionStr(const std::exception& e) {
   return folly::to<fbstring>(demangle(typeid(e)), ": ", e.what());
 }
@@ -372,6 +366,14 @@ inline fbstring exceptionStr(std::exception_ptr ep) {
   }
 }
 
+template<typename E>
+auto exceptionStr(const E& e)
+  -> typename std::enable_if<!std::is_base_of<std::exception, E>::value,
+                             fbstring>::type
+{
+  return folly::to<fbstring>(demangle(typeid(e)));
+}
+
 /*
  * Split a string into a list of tokens by delimiter.
  *
index f2162567dd8830b2e8d91d7545653e95dbfc0f3c..111945e8310c503f28c7b1d5794e5e363d40b301 100644 (file)
@@ -1077,6 +1077,13 @@ TEST(String, humanify) {
   EXPECT_EQ("0x61ffffffffff", humanify(string("a\xff\xff\xff\xff\xff")));
 }
 
+TEST(String, exceptionStr) {
+  EXPECT_EQ(exceptionStr(0), "int");
+  EXPECT_EQ(exceptionStr(std::exception()), "std::exception: std::exception");
+  EXPECT_EQ(exceptionStr(std::runtime_error("folly")),
+            "std::runtime_error: folly");
+}
+
 namespace {
 
 /**