X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FExceptionWrapper.cpp;h=f2fa016437558dc3be01c13a29e970f272b087af;hb=3f4a8ae005738662fbbca4a85c959df2bf0d059b;hp=d819c603e269ccfc812708931b2e605eb24177a8;hpb=eaa278a52d9d5878021637a850627b853009c8bd;p=folly.git diff --git a/folly/ExceptionWrapper.cpp b/folly/ExceptionWrapper.cpp index d819c603..f2fa0164 100644 --- a/folly/ExceptionWrapper.cpp +++ b/folly/ExceptionWrapper.cpp @@ -15,50 +15,91 @@ */ #include -#include #include +#include + namespace folly { -[[noreturn]] void exception_wrapper::throwException() const { - if (throwfn_) { - throwfn_(*item_); - } else if (eptr_) { - std::rethrow_exception(eptr_); +exception_wrapper::VTable const exception_wrapper::uninit_{ + &noop_, + &noop_, + &noop_, + &noop_, + &uninit_type_, + &noop_, + &noop_}; + +exception_wrapper::VTable const exception_wrapper::ExceptionPtr::ops_{ + copy_, + move_, + delete_, + throw_, + type_, + get_exception_, + get_exception_ptr_}; + +exception_wrapper::VTable const exception_wrapper::SharedPtr::ops_{ + copy_, + move_, + delete_, + throw_, + type_, + get_exception_, + get_exception_ptr_}; + +namespace { +std::exception const* get_std_exception_(std::exception_ptr eptr) noexcept { + try { + std::rethrow_exception(eptr); + } catch (const std::exception& ex) { + return &ex; + } catch (...) { + return nullptr; } - std::cerr - << "Cannot use `throwException` with an empty folly::exception_wrapper" - << std::endl; - std::terminate(); } +} // namespace -fbstring exception_wrapper::class_name() const { - if (item_) { - auto& i = *item_; - return demangle(typeid(i)); - } else if (eptr_ && eobj_) { - return demangle(typeid(*eobj_)); - } else if (eptr_ && etype_) { - return demangle(*etype_); - } else { - return fbstring(); +exception_wrapper exception_wrapper::from_exception_ptr( + std::exception_ptr const& ptr) noexcept { + if (!ptr) { + return exception_wrapper(); + } + try { + std::rethrow_exception(ptr); + } catch (std::exception& e) { + return exception_wrapper(std::current_exception(), e); + } catch (...) { + return exception_wrapper(std::current_exception()); } } -fbstring exception_wrapper::what() const { - if (item_) { - return exceptionStr(*item_); - } else if (eptr_ && eobj_) { - return class_name() + ": " + eobj_->what(); - } else if (eptr_ && etype_) { - return class_name(); - } else { - return class_name(); +exception_wrapper::exception_wrapper(std::exception_ptr ptr) noexcept + : exception_wrapper{} { + if (ptr) { + if (auto e = get_std_exception_(ptr)) { + LOG(DFATAL) + << "Performance error: Please construct exception_wrapper with a " + "reference to the std::exception along with the " + "std::exception_ptr."; + *this = exception_wrapper{std::move(ptr), *e}; + } else { + Unknown uk; + *this = exception_wrapper{ptr, uk}; + } } } -fbstring exceptionStr(const exception_wrapper& ew) { +[[noreturn]] void exception_wrapper::onNoExceptionError( + char const* const name) { + std::ios_base::Init ioinit_; // ensure std::cerr is alive + std::cerr << "Cannot use `" << name + << "` with an empty folly::exception_wrapper" << std::endl; + std::terminate(); +} + +fbstring exceptionStr(exception_wrapper const& ew) { return ew.what(); } -} // folly +} // namespace folly