Using a library that has a method like this one:
std::future<bool> action();
I find my self in a situation where I have to conform with project specific enum
return types like:
enum Result { Ok, Failed, ConnectionDown, ServerError };
and the call site of action looks like this:
std::future<Result> act()
{
try {
return _actor->action(); // This returns a different type :(
// What to do here ??? ^
}
catch (ConnectionError const& e)
{
return std::make_ready_future<Result>(Result::ConnectionError);
}
catch (ServerError const& e)
{
return std::make_ready_future<Result>(Result::ServerError);
}
}
so essentially the library doesn't have specific return codes for error cases, they are rather emitted as exceptions. Handling that is easy because I can construct ready futures with the appropriate value. The problem (ironically) is with the non exceptional path, where the library's std::future<bool>
has to be transformed to std::future<Result>
.
It's pointless to .get()
the result and construct a ready future based on its value (true -> Ok, false -> Failed) because this way I'm removing asynchronicity from my function. Is there a better way to handle this?
CodePudding user response:
Waiting for continuation function (std::experimental::future::then
)
, you probably want something like:
std::future<Result> act()
{
return std::async([&](){
try {
if (_actor->action().get()) {
return Result::Ok;
} else {
return Result::Failed;
}
}
catch (ConnectionError const& e) {
return Result::ConnectionError;
}
catch (ServerError const& e) {
return Result::ServerError;
}
});
}