When I introduced a basic implementation of a promise type, I noted that the return_value
method or return_void
method is called when the coroutine performs a co_return
. But what happens if the return_value
or return_void
method raises an exception?
void return_value(T const& v) const { holder.set_result(v); // what if the copy constructor throws? } void unhandled_exception() const noexcept { holder.set_exception(std::current_exception()); }
What if we take an exception trying to set the result, say because the copy constructor threw an exception? Do we have to catch the exception and convert it to a holder.set_exception
?
void return_value(T const& v) const { // Do I have to wrap the set_result? try { holder.set_result(v); } catch (...) { holder.set_exception(std::current_exception()); } }
Let’s go back and look at the transformation that the compiler performs when it generates a coroutine:
return_type MyCoroutine(args...) { create coroutine state copy parameters to coroutine frame promise_type p; auto return_object = p.get_return_object(); try { co_await p.initial_suspend(); // ¹ coroutine function body } catch (...) { p.unhandled_exception(); } co_await p.final_suspend(); destruct promise p destruct parameters in coroutine frame destroy coroutine state }
The return_value
and return_void
happen as part of the transformation of the co_return
statement, and that is part of the section marked coroutine function body. Therefore, if an exception occurs during return_value
or return_void
, it is caught by the catch (...)
and is delivered to unhandled_exception
.
In other words, the compiler already wrapped your return_value
and return_void
functions inside a try
/catch
so you don’t have to.
Note however that there is no try
/catch
wrapped around the call to unhandled_
, so that method should be careful not throw any exceptions.
Okay, so that was a brief digression on exceptions that occur when returning a value to the promise. Next time, we’ll look at another improvement to our coroutine promise implementation.
0 comments