Commit accce27e authored by Marc Horowitz's avatar Marc Horowitz Committed by Sara Golemon

fix exceptionStr to work for derived classes of std::exception

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
parent c9f5e539
......@@ -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>
......
......@@ -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.
*
......
......@@ -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 {
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment