@@ -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
431438template <class FuncHead , class ... FuncTail>
0 commit comments