Commit b42e5ace authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

cut try_and_catch overload taking explicit types to catch

Summary: There is no longer compelling reason to keep this overload since it is relatively cheap to inspect any `exception_wrapper` or `exception_ptr`, no matter from which exception object type it is constructed.

Reviewed By: luciang

Differential Revision: D26877547

fbshipit-source-id: d9a38c9a56a47b9453eda2d9e8abf7586c8aab61
parent 6a4d3877
......@@ -581,62 +581,8 @@ inline void swap(exception_wrapper& a, exception_wrapper& b) noexcept {
// For consistency with exceptionStr() functions in ExceptionString.h
fbstring exceptionStr(exception_wrapper const& ew);
namespace detail {
template <typename F>
inline exception_wrapper try_and_catch_(F&& f) {
return (f(), exception_wrapper());
}
template <typename F, typename Ex, typename... Exs>
inline exception_wrapper try_and_catch_(F&& f) {
try {
return try_and_catch_<F, Exs...>(std::forward<F>(f));
} catch (Ex&) {
return exception_wrapper(std::current_exception());
}
}
} // namespace detail
//! `try_and_catch` is a simple replacement for `try {} catch(){}`` that allows
//! you to specify which derived exceptions you would like to catch and store in
//! an `exception_wrapper`.
//!
//! Because we cannot build an equivalent of `std::current_exception()`, we need
//! to catch every derived exception that we are interested in catching.
//!
//! Exceptions should be listed in the reverse order that you would write your
//! catch statements (that is, `std::exception&` should be first).
//!
//! \par Example Usage:
//! \code
//! // This catches my runtime_error and if I call throw_exception() on ew, it
//! // will throw a runtime_error
//! auto ew = folly::try_and_catch<std::exception, std::runtime_error>([=]() {
//! if (badThingHappens()) {
//! throw std::runtime_error("ZOMG!");
//! }
//! });
//!
//! // This will catch the exception and if I call throw_exception() on ew, it
//! // will throw a std::exception
//! auto ew = folly::try_and_catch<std::exception, std::runtime_error>([=]() {
//! if (badThingHappens()) {
//! throw std::exception();
//! }
//! });
//!
//! // This will not catch the exception and it will be thrown.
//! auto ew = folly::try_and_catch<std::runtime_error>([=]() {
//! if (badThingHappens()) {
//! throw std::exception();
//! }
//! });
//! \endcode
template <typename Exn, typename... Exns, typename F>
[[deprecated("no longer specify exception types explicitly")]] exception_wrapper
try_and_catch(F&& fn) {
return detail::try_and_catch_<F, Exn, Exns...>(std::forward<F>(fn));
}
//! `try_and_catch` is a convenience for `try {} catch(...) {}`` that returns an
//! `exception_wrapper` with the thrown exception, if any.
template <typename F>
exception_wrapper try_and_catch(F&& fn) noexcept {
try {
......
......@@ -116,54 +116,6 @@ TEST(ExceptionWrapper, members) {
}
TEST(ExceptionWrapper, try_and_catch_test) {
std::string expected = "payload";
// Catch rightmost matching exception type
FOLLY_PUSH_WARNING
FOLLY_GNU_DISABLE_WARNING("-Wdeprecated-declarations")
exception_wrapper ew = try_and_catch<std::exception, std::runtime_error>(
[=]() { throw std::runtime_error(expected); });
FOLLY_POP_WARNING
EXPECT_TRUE(bool(ew));
EXPECT_EQ(ew.what(), kRuntimeErrorClassName + ": payload");
EXPECT_EQ(ew.class_name(), kRuntimeErrorClassName);
auto rep = ew.is_compatible_with<std::runtime_error>();
EXPECT_TRUE(rep);
// Changing order is like catching in wrong order. Beware of this in your
// code.
FOLLY_PUSH_WARNING
FOLLY_GNU_DISABLE_WARNING("-Wdeprecated-declarations")
auto ew2 = try_and_catch<std::runtime_error, std::exception>(
[=]() { throw std::runtime_error(expected); });
FOLLY_POP_WARNING
EXPECT_TRUE(bool(ew2));
// We are catching a std::exception, not std::runtime_error.
// But, we can still get the actual type if we want it.
rep = ew2.is_compatible_with<std::runtime_error>();
EXPECT_TRUE(rep);
// Catches even if not rightmost.
FOLLY_PUSH_WARNING
FOLLY_GNU_DISABLE_WARNING("-Wdeprecated-declarations")
auto ew3 = try_and_catch<std::exception, std::runtime_error>(
[]() { throw std::exception(); });
FOLLY_POP_WARNING
EXPECT_TRUE(bool(ew3));
EXPECT_EQ(ew3.what(), kExceptionClassName + ": " + std::exception().what());
EXPECT_EQ(ew3.class_name(), kExceptionClassName);
rep = ew3.is_compatible_with<std::runtime_error>();
EXPECT_FALSE(rep);
// If does not catch, throws.
FOLLY_PUSH_WARNING
FOLLY_GNU_DISABLE_WARNING("-Wdeprecated-declarations")
EXPECT_THROW(
try_and_catch<std::runtime_error>([]() { throw std::exception(); }),
std::exception);
FOLLY_POP_WARNING
// No list
auto ew4 = try_and_catch([] { throw 17; });
EXPECT_TRUE(bool(ew4));
EXPECT_TRUE(ew4.is_compatible_with<int>());
......@@ -172,25 +124,13 @@ TEST(ExceptionWrapper, try_and_catch_test) {
TEST(ExceptionWrapper, with_exception_test) {
int expected = 23;
exception_wrapper ew = exception_wrapper::from_exception_ptr(
std::make_exception_ptr(IntException(expected)));
auto ew = exception_wrapper{std::make_exception_ptr(IntException(expected))};
EXPECT_TRUE(bool(ew));
EXPECT_EQ(ew.what(), kIntExceptionClassName + ": int == 23");
EXPECT_EQ(ew.class_name(), kIntExceptionClassName);
EXPECT_TRUE(ew.with_exception(
[&](const IntException& ie) { EXPECT_EQ(ie.getInt(), expected); }));
exception_wrapper ew2 = exception_wrapper::from_exception_ptr(
std::make_exception_ptr(IntException(expected)));
EXPECT_TRUE(bool(ew2));
EXPECT_EQ(ew2.what(), kIntExceptionClassName + ": int == 23");
EXPECT_EQ(ew2.class_name(), kIntExceptionClassName);
bool res = ew2.with_exception([&](AbstractIntException& ie) {
EXPECT_EQ(ie.getInt(), expected);
EXPECT_TRUE(dynamic_cast<IntException*>(&ie));
});
EXPECT_TRUE(res);
// Test with const this. If this compiles and does not crash due to
// infinite loop when it runs, it succeeds.
const exception_wrapper& cew = ew;
......@@ -216,16 +156,10 @@ TEST(ExceptionWrapper, with_exception_test) {
TEST(ExceptionWrapper, get_or_make_exception_ptr_test) {
int expected = 23;
exception_wrapper ew = exception_wrapper::from_exception_ptr(
std::make_exception_ptr(IntException(expected)));
auto ew = exception_wrapper{std::make_exception_ptr(IntException(expected))};
std::exception_ptr eptr = ew.to_exception_ptr();
EXPECT_THROW(std::rethrow_exception(eptr), IntException);
exception_wrapper ew2 = exception_wrapper::from_exception_ptr(
std::make_exception_ptr(IntException(expected)));
eptr = ew2.to_exception_ptr();
EXPECT_THROW(std::rethrow_exception(eptr), IntException);
// Test with const this.
const exception_wrapper& cew = ew;
eptr = cew.to_exception_ptr();
......@@ -494,11 +428,7 @@ TEST(ExceptionWrapper, with_exception_deduction_functor_lvalue) {
TEST(ExceptionWrapper, non_std_exception_test) {
int expected = 17;
FOLLY_PUSH_WARNING
FOLLY_GNU_DISABLE_WARNING("-Wdeprecated-declarations")
exception_wrapper ew =
try_and_catch<std::exception, int>([=]() { throw expected; });
FOLLY_POP_WARNING
auto ew = exception_wrapper{std::make_exception_ptr(expected)};
EXPECT_TRUE(bool(ew));
EXPECT_FALSE(ew.is_compatible_with<std::exception>());
EXPECT_TRUE(ew.is_compatible_with<int>());
......
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