From: Radosław Zarzyński Date: Wed, 30 Mar 2022 13:02:20 +0000 (+0200) Subject: crimson/common: let errorator's handlers to conditionally forward errors X-Git-Tag: v18.0.0~1144^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fc3d1b2f014794532631f5d4b380ca387721948c;p=ceph.git crimson/common: let errorator's handlers to conditionally forward errors The use case is like the following one: ```diff diff --git a/src/crimson/osd/replicated_recovery_backend.cc b/src/crimson/osd/replicated_recovery_backend.cc index a96f1b8dd2b..055add2e407 100644 --- a/src/crimson/osd/replicated_recovery_backend.cc +++ b/src/crimson/osd/replicated_recovery_backend.cc @@ -516,10 +516,14 @@ ReplicatedRecoveryBackend::read_object_for_push_op( recovered_to = push_op->data_included.range_end(); } return seastar::make_ready_future(recovered_to); - }, PGBackend::read_errorator::all_same_way([](auto e) { + }, PGBackend::read_errorator::all_same_way([](auto e, auto&& e_raw) -> PGBackend::read_errorator::future { logger().debug("build_push_op: read exception"); - return seastar::make_exception_future(e); - })); + if (42) { + return std::move(e_raw); + } else { + return seastar::make_exception_future(e); + } + })).handle_error_interruptible(PGBackend::read_errorator::discard_all{}); } RecoveryBackend::interruptible_future<> ``` Signed-off-by: Radosław Zarzyński --- diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index 5f817eec918e..71dddf2b5a1d 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -131,8 +131,14 @@ struct unthrowable_wrapper : error_t> { static auto handle(Func&& func) { return [ func = std::forward(func) - ] (const unthrowable_wrapper&) mutable -> decltype(auto) { - if constexpr (std::is_invocable_v) { + ] (const unthrowable_wrapper& raw_error) mutable -> decltype(auto) { + if constexpr (std::is_invocable_v) { + // check whether the handler wants to take the raw error object which + // would be the case if it wants conditionally handle-or-pass-further. + return std::invoke(std::forward(func), + ErrorV, + std::move(raw_error)); + } else if constexpr (std::is_invocable_v) { return std::invoke(std::forward(func), ErrorV); } else { return std::invoke(std::forward(func)); @@ -197,13 +203,17 @@ struct stateful_error_t : error_t> { return [ func = std::forward(func) ] (stateful_error_t&& e) mutable -> decltype(auto) { - if constexpr (std::is_invocable_v) { + if constexpr (std::is_invocable_v) { return std::invoke(std::forward(func)); } try { std::rethrow_exception(e.ep); } catch (const ErrorT& obj) { - return std::invoke(std::forward(func), obj); + if constexpr (std::is_invocable_v) { + return std::invoke(std::forward(func), obj, e); + } else if constexpr (std::is_invocable_v) { + return std::invoke(std::forward(func), obj); + } } ceph_abort_msg("exception type mismatch -- impossible!"); };