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>
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());
}
}
}
+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.
*
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 {
/**