Skip to content

Commit 3bbbf0c

Browse files
committed
crimson/common/errorator: introduce take_exception_from_future
Signed-off-by: Matan Breizman <[email protected]>
1 parent e3ad98c commit 3bbbf0c

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

src/crimson/common/errorator.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,8 @@ class maybe_handle_error_t {
381381
static_assert(!std::is_same_v<return_t, void>,
382382
"error handlers mustn't return void");
383383

384+
auto ep = take_exception_from_future();
385+
384386
// Any assert_* handler we have:
385387
// assert_failure, assert_all and assert_all_func_t
386388
// are expected to return void since we actually abort in them.
@@ -389,7 +391,6 @@ class maybe_handle_error_t {
389391
// label of: no_touch_error_marker. Otherwise we would fail the above
390392
// static assertion.
391393
if constexpr (std::is_same_v<return_t, no_touch_error_marker>) {
392-
[[maybe_unused]] auto &&ep = std::move(result).get_exception();
393394
std::ignore = std::invoke(std::forward<ErrorVisitorT>(errfunc),
394395
ErrorT::error_t::from_exception_ptr(std::move(ep)));
395396
} else {
@@ -405,12 +406,9 @@ class maybe_handle_error_t {
405406
// `catch`. The limitation here is lack of support for hierarchies
406407
// of exceptions. The code below checks for exact match only while
407408
// `catch` would allow to match against a base class as well.
408-
// However, this shouldn't be a big issue for `errorator` as Error
409-
// Visitors are already checked for exhaustiveness at compile-time.
409+
// However, this shouldn't be a big issue for `errorator` as
410+
// ErrorVisitorT are already checked for exhaustiveness at compile-time.
410411
if (type_info == ErrorT::error_t::get_exception_ptr_type_info()) {
411-
// set `state::invalid` in internals of `seastar::future` to not
412-
// call `report_failed_future()` during `operator=()`.
413-
[[maybe_unused]] auto &&ep = std::move(result).get_exception();
414412
if constexpr (std::is_assignable_v<decltype(result), return_t>) {
415413
result = std::invoke(std::forward<ErrorVisitorT>(errfunc),
416414
ErrorT::error_t::from_exception_ptr(std::move(ep)));
@@ -426,6 +424,15 @@ class maybe_handle_error_t {
426424
auto get_result() && {
427425
return std::move(result);
428426
}
427+
428+
// seastar::future::get_exception()&& calls take_exception() internally.
429+
// This will result in the future state to be "state::invalid".
430+
// That way when using seastar::future `operator=()`,
431+
// report_failed_future() won't be called.
432+
std::exception_ptr take_exception_from_future() {
433+
auto&& ep = std::move(result).get_exception();
434+
return ep;
435+
}
429436
};
430437

431438
template <class FuncHead, class... FuncTail>

0 commit comments

Comments
 (0)