From 3bbbf0c8ed1f481c3268b5d1e6b7624aad0b8c58 Mon Sep 17 00:00:00 2001 From: Matan Breizman Date: Thu, 10 Apr 2025 10:07:08 +0000 Subject: [PATCH] crimson/common/errorator: introduce take_exception_from_future Signed-off-by: Matan Breizman --- src/crimson/common/errorator.h | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index 1bc9ff7955345..b13afd8334076 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -381,6 +381,8 @@ public: static_assert(!std::is_same_v, "error handlers mustn't return void"); + auto ep = take_exception_from_future(); + // Any assert_* handler we have: // assert_failure, assert_all and assert_all_func_t // are expected to return void since we actually abort in them. @@ -389,7 +391,6 @@ public: // label of: no_touch_error_marker. Otherwise we would fail the above // static assertion. if constexpr (std::is_same_v) { - [[maybe_unused]] auto &&ep = std::move(result).get_exception(); std::ignore = std::invoke(std::forward(errfunc), ErrorT::error_t::from_exception_ptr(std::move(ep))); } else { @@ -405,12 +406,9 @@ public: // `catch`. The limitation here is lack of support for hierarchies // of exceptions. The code below checks for exact match only while // `catch` would allow to match against a base class as well. - // However, this shouldn't be a big issue for `errorator` as Error - // Visitors are already checked for exhaustiveness at compile-time. + // However, this shouldn't be a big issue for `errorator` as + // ErrorVisitorT are already checked for exhaustiveness at compile-time. if (type_info == ErrorT::error_t::get_exception_ptr_type_info()) { - // set `state::invalid` in internals of `seastar::future` to not - // call `report_failed_future()` during `operator=()`. - [[maybe_unused]] auto &&ep = std::move(result).get_exception(); if constexpr (std::is_assignable_v) { result = std::invoke(std::forward(errfunc), ErrorT::error_t::from_exception_ptr(std::move(ep))); @@ -426,6 +424,15 @@ public: auto get_result() && { return std::move(result); } + + // seastar::future::get_exception()&& calls take_exception() internally. + // This will result in the future state to be "state::invalid". + // That way when using seastar::future `operator=()`, + // report_failed_future() won't be called. + std::exception_ptr take_exception_from_future() { + auto&& ep = std::move(result).get_exception(); + return ep; + } }; template -- 2.39.5