chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.94k stars 1.22k forks source link

co_await promise(use_awaitable) does not propagate exceptions (returns bogus value) #1204

Open gummif opened 1 year ago

gummif commented 1 year ago

Complete example. I expected the promise to throw, but it returns a default constructed int instead:

#include <iostream>
#include <cassert>
#include <boost/asio/use_awaitable.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/deferred.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/experimental/promise.hpp>
#include <boost/asio/experimental/use_promise.hpp>

using namespace boost::asio;
using namespace boost::asio::experimental;

awaitable<int> f()
{
    throw std::runtime_error("foo");
    co_return 42;
}

int main()
{
    io_context ioc;
    co_spawn(ioc, [&]() -> awaitable<void>{
        try
        {
            auto promise = co_spawn(ioc, f(), use_promise);
            //int r = co_await promise(deferred); // does not compile
            int r = co_await promise(use_awaitable); // does not throw, triggers assert
            std::cout << r << std::endl; // r is 0
            assert(false);
        }
        catch (const std::exception& e)
        {
            std::cout << e.what() << std::endl;
        }
    }, detached);
    ioc.run();
}