diff --git a/include/spinscale/co/group.h b/include/spinscale/co/group.h index 5bac0d9..46fec76 100644 --- a/include/spinscale/co/group.h +++ b/include/spinscale/co/group.h @@ -564,10 +564,10 @@ struct Group memberAdapterCoro(memberInvoker, settlementIndex); } - void checkForAndReThrowGroupExceptions() const + std::exception_ptr captureAggregatedGroupExceptions() const { std::ostringstream ostream; - bool doThrow = false; + bool hasFailures = false; for (auto &item : s.rsrc.settlements) { @@ -577,7 +577,7 @@ struct Group assert(item.calleeException); - doThrow = true; + hasFailures = true; ostream << "Exc thrown in Group Adapter: "; try { std::rethrow_exception(item.calleeException); @@ -589,8 +589,19 @@ struct Group ostream << "\n"; } - if (doThrow) { - throw std::runtime_error(ostream.str()); + if (!hasFailures) { + return nullptr; + } + + return std::make_exception_ptr(std::runtime_error(ostream.str())); + } + + void checkForAndReThrowGroupExceptions() const + { + std::exception_ptr aggregatedException = + captureAggregatedGroupExceptions(); + if (aggregatedException) { + std::rethrow_exception(aggregatedException); } } diff --git a/include/spinscale/multiOperationResultSet.h b/include/spinscale/multiOperationResultSet.h index 02965c0..1d415c4 100644 --- a/include/spinscale/multiOperationResultSet.h +++ b/include/spinscale/multiOperationResultSet.h @@ -1,6 +1,8 @@ #ifndef MULTI_OPERATION_RESULT_SET_H #define MULTI_OPERATION_RESULT_SET_H +#include + namespace sscl { /** Plain aggregate for fan-out / fan-in results returned from coroutines. */ @@ -24,6 +26,25 @@ struct MultiOperationResultSet unsigned int nFailed; }; +/** Fan-out / fan-in counts plus optional aggregated member failure. */ +struct MultiOperationResultSetWithException +{ + MultiOperationResultSetWithException() = default; + + MultiOperationResultSetWithException( + MultiOperationResultSet resultsIn, + std::exception_ptr memberFailureExceptionIn = nullptr) + : results(resultsIn), + memberFailureException(memberFailureExceptionIn) + {} + + bool hasMemberFailure() const + { return memberFailureException != nullptr; } + + MultiOperationResultSet results; + std::exception_ptr memberFailureException = nullptr; +}; + } // namespace sscl #endif // MULTI_OPERATION_RESULT_SET_H