Commit 8aedb408 authored by Andrii Grynenko's avatar Andrii Grynenko Committed by Facebook Github Bot

co_throw

Summary: An alternative to co_return Try that works for Task<void>

Reviewed By: yfeldblum

Differential Revision: D19136334

fbshipit-source-id: 72a18482b326dbc40b691712a5fd311efad45785
parent d888f430
......@@ -29,6 +29,7 @@
#include <folly/Try.h>
#include <folly/experimental/coro/CurrentExecutor.h>
#include <folly/experimental/coro/Invoke.h>
#include <folly/experimental/coro/Throw.h>
#include <folly/experimental/coro/Traits.h>
#include <folly/experimental/coro/Utils.h>
#include <folly/experimental/coro/ViaIfAsync.h>
......@@ -156,6 +157,13 @@ class TaskPromise : public TaskPromiseBase {
return result_;
}
using TaskPromiseBase::await_transform;
auto await_transform(co_throw ex) {
result_.emplaceException(std::move(ex.exception()));
return final_suspend();
}
private:
Try<StorageType> result_;
};
......@@ -182,6 +190,13 @@ class TaskPromise<void> : public TaskPromiseBase {
return result_;
}
using TaskPromiseBase::await_transform;
auto await_transform(co_throw ex) {
result_.emplaceException(std::move(ex.exception()));
return final_suspend();
}
private:
Try<void> result_;
};
......
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <folly/ExceptionWrapper.h>
namespace folly {
namespace coro {
class co_throw {
public:
explicit co_throw(exception_wrapper ex) : ex_(std::move(ex)) {}
const exception_wrapper& exception() const {
return ex_;
}
exception_wrapper& exception() {
return ex_;
}
private:
exception_wrapper ex_;
};
} // namespace coro
} // namespace folly
......@@ -575,4 +575,49 @@ TEST_F(CoroTest, DefaultConstructible) {
}());
}
TEST(Coro, CoReturnTry) {
EXPECT_EQ(42, folly::coro::blockingWait([]() -> folly::coro::Task<int> {
co_return folly::Try<int>(42);
}()));
struct ExpectedException : public std::runtime_error {
ExpectedException() : std::runtime_error("ExpectedException") {}
};
EXPECT_THROW(
folly::coro::blockingWait([]() -> folly::coro::Task<int> {
co_return folly::Try<int>(ExpectedException());
}()),
ExpectedException);
EXPECT_EQ(42, folly::coro::blockingWait([]() -> folly::coro::Task<int> {
folly::Try<int> t(42);
co_return t;
}()));
EXPECT_EQ(42, folly::coro::blockingWait([]() -> folly::coro::Task<int> {
const folly::Try<int> tConst(42);
co_return tConst;
}()));
}
TEST(Coro, CoThrow) {
struct ExpectedException : public std::runtime_error {
ExpectedException() : std::runtime_error("ExpectedException") {}
};
EXPECT_THROW(
folly::coro::blockingWait([]() -> folly::coro::Task<int> {
co_await folly::coro::co_throw(ExpectedException());
EXPECT_TRUE(false) << "unreachable";
co_return 42;
}()),
ExpectedException);
EXPECT_THROW(
folly::coro::blockingWait([]() -> folly::coro::Task<void> {
co_await folly::coro::co_throw(ExpectedException());
EXPECT_TRUE(false) << "unreachable";
}()),
ExpectedException);
}
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment