add promised network request

This commit is contained in:
2019-07-15 16:51:48 +07:00
parent 8ae456b691
commit a2cf5dc298
3 changed files with 94 additions and 4 deletions

View File

@@ -21,6 +21,46 @@ namespace e2d
}
};
//
// request_network_error
//
class request_network_error final : public exception {
public:
request_network_error() = default;
request_network_error(str error)
: error_(std::move(error)) {}
const char* what() const noexcept final {
return error_.empty()
? "request network error"
: error_.c_str();
}
private:
str error_;
};
//
// request_cancelled_exception
//
class request_cancelled_exception : public exception {
public:
const char* what() const noexcept override {
return "request cancelled exception";
}
};
//
// network_request
//
struct network_request final {
net::request request;
stdex::promise<net::response> promise;
};
//
// network
//
@@ -29,6 +69,9 @@ namespace e2d
public:
network();
~network() noexcept;
network_request request(net::request_builder& rb);
network_request request(net::request_builder&& rb);
private:
class internal_state;
std::unique_ptr<internal_state> state_;

View File

@@ -22,4 +22,27 @@ namespace e2d
network::network()
: state_(new internal_state()) {}
network::~network() noexcept = default;
network_request network::request(net::request_builder& rb) {
return request(std::move(rb));
}
network_request network::request(net::request_builder&& rb) {
if ( rb.callback() ) {
throw bad_network_operation();
}
stdex::promise<net::response> promise;
rb.callback([promise](net::request request) mutable {
if ( request.is_done() ) {
promise.resolve(request.take());
return;
}
if ( request.status() == net::req_status::cancelled ) {
promise.reject(request_cancelled_exception());
} else {
promise.reject(request_network_error(request.get_error()));
}
});
return {rb.send(), std::move(promise)};
}
}

View File

@@ -11,9 +11,33 @@ TEST_CASE("network"){
network n;
SECTION("request"){
auto request = net::request_builder()
.url("http://httpbin.org/status/201")
.send();
REQUIRE(request.take().http_code() == 201u);
{
auto nreq = n.request(net::request_builder()
.url("http://httpbin.org/status/201"));
nreq.promise.then([](const net::response& response){
REQUIRE(response.http_code() == 201u);
}).except([](std::exception_ptr){
REQUIRE(false);
}).wait();
}
{
auto nreq = n.request(net::request_builder()
.url("http://httpbin.org/delay/2"));
REQUIRE(nreq.request.cancel());
nreq.promise.then([](const net::response&){
REQUIRE(false);
}).except([](std::exception_ptr e){
try {
std::rethrow_exception(e);
} catch (const request_cancelled_exception&) {
REQUIRE(true);
} catch (...) {
REQUIRE(false);
}
}).wait();
}
}
}