Lets say for example I have a boost::asio::steady_timer timer that I want to async wait on with boost::asio::steady_timer::async_wait. In the old way I get errors as code parameter in my completion handler i.e. my lambda like
timer.async_wait([](const auto &boost_error) {
//check boost_error
});
With Co routines I am able to co_await when using boost::asio::use_awaitable as
co_await timer.async_wait(boost::asio::use_awaitable);
However the error handling has changed: In order to catch errors, like an canceled timer, I have to wrap my co_await in a try/catch block.
Can I get boost to let me await on the async operation but giving me the error as a code, like
std::variant<void, error_code> = co_await timer.async_wait(boost::asio::use_awaitable);
?
Close: as_tuple(use_awaitable) works almost exactly like that:
Live On Compiler Explorer
#include <boost/asio.hpp>
#include <boost/asio/experimental/awaitable_operators.hpp>
#include <iostream>
namespace asio = boost::asio;
using namespace std::chrono_literals;
using namespace asio::experimental::awaitable_operators;
asio::awaitable<void> timer(auto duration) {
auto [ec] = co_await asio::steady_timer{co_await asio::this_coro::executor, duration}.async_wait(
as_tuple(asio::use_awaitable));
std::cout << "Wait for " << (duration / 1.s) << "s: " << ec.message() << std::endl;
};
int main() {
asio::io_context ioc;
asio::co_spawn(ioc, timer(3s) || timer(1500ms), asio::detached);
ioc.run();
}
Prints:
Wait for 1.5s: Success
Wait for 3s: Operation canceled
Alternative adaptors: asio::redirect_error and asio::as_single
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With