From accce27e08a353124c9962704a3661bbccf1d942 Mon Sep 17 00:00:00 2001 From: Marc Horowitz Date: Wed, 3 Sep 2014 19:32:36 -0700 Subject: [PATCH] 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 --- folly/ExceptionWrapper.h | 3 +-- folly/String.h | 18 ++++++++++-------- folly/test/StringTest.cpp | 7 +++++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/folly/ExceptionWrapper.h b/folly/ExceptionWrapper.h index 14f2b71b..08082232 100644 --- a/folly/ExceptionWrapper.h +++ b/folly/ExceptionWrapper.h @@ -275,8 +275,7 @@ class try_and_catch : typename std::enable_if::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(e)).toStdString(); + this->estr_ = exceptionStr(e).toStdString(); } template diff --git a/folly/String.h b/folly/String.h index 223c4907..14fda430 100644 --- a/folly/String.h +++ b/folly/String.h @@ -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 -fbstring exceptionStr(const T& e) { - return folly::to(demangle(typeid(e))); -} - inline fbstring exceptionStr(const std::exception& e) { return folly::to(demangle(typeid(e)), ": ", e.what()); } @@ -372,6 +366,14 @@ inline fbstring exceptionStr(std::exception_ptr ep) { } } +template +auto exceptionStr(const E& e) + -> typename std::enable_if::value, + fbstring>::type +{ + return folly::to(demangle(typeid(e))); +} + /* * Split a string into a list of tokens by delimiter. * diff --git a/folly/test/StringTest.cpp b/folly/test/StringTest.cpp index f2162567..111945e8 100644 --- a/folly/test/StringTest.cpp +++ b/folly/test/StringTest.cpp @@ -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 { /** -- 2.34.1