Before coroutines, when an exception was thrown out of a callback, like via boost::asio::post the exception would propagate out of boost::asio::io_context::run(). However if one uses coroutines via boost::asio::co_spawn, in a fire and forget mode like with boost::asio::detached the exceptions are not thrown out of run(). In similar question an anwser, https://stackoverflow.com/a/68042350/3537677, refered to using a completion handler with the signature of void (std::exception_ptr,...) however I could not get the code executed in that handler at all.
So how do I get exceptions out of co_routines propagated to io_context::run or, if that is not possible, to define a exception handling clause i.e. to co_spawn? My MRE:
#include <iostream>
#include <boost/asio.hpp>
boost::asio::awaitable<void> coroutine() {
std::cout << "Coroutine executes...\n";
throw std::runtime_error("Test throw from coroutine!");
co_return;
}
int main(int argc, char* argv[]) {
boost::asio::io_context context;
boost::asio::co_spawn(context, coroutine(), boost::asio::detached);
boost::asio::co_spawn(context, coroutine(), [] (std::exception_ptr ptr) {
std::cout << "Rethrowing in completion handler\n"; //Doesn't get executed
throw ptr;
});
boost::asio::post(context, [] () {
throw std::runtime_error("Test throw from post!");
});
std::thread t([&context]() {
try {
while (true) {
context.run();
return;
}
} catch (std::exception &e) {
std::cerr << "Exception in context::run(): " << e.what() << "\n";
}
});
t.join();
}
Actual Output:
Coroutine executes...
Coroutine executes...
Exception in context::run(): Test throw from post!
Process finished with exit code 0
Desired Output:
...
Coroutine executes...
std::cout << "Rethrowing in completion handler\n";
Exception in context::run(): Test throw from coroutine!
Exception in context::run(): Test throw from post!
Process finished with exit code 0
throw ptrdoesn't do what you think it does.Use
Next up, handling exceptions from
io_contextis subtly different: you stop theio_contextprematurely.Slightly simplified and improved output:
Live On Compiler Explorer
Prints