diff --git a/include/ylt/coro_rpc/impl/context.hpp b/include/ylt/coro_rpc/impl/context.hpp index b2de5ca61..c61e5bd79 100644 --- a/include/ylt/coro_rpc/impl/context.hpp +++ b/include/ylt/coro_rpc/impl/context.hpp @@ -75,14 +75,14 @@ class context_base { using return_type = return_msg_type; - void response_error(coro_rpc::errc error_code, std::string_view error_msg) { + void response_error(coro_rpc::err_code error_code, + std::string_view error_msg) { if (!check_status()) AS_UNLIKELY { return; }; self_->conn_->template response_error( error_code, error_msg, self_->req_head_, self_->is_delay_); } - - void response_error(coro_rpc::errc error_code) { + void response_error(coro_rpc::err_code error_code) { response_error(error_code, make_error_message(error_code)); } /*! @@ -190,13 +190,8 @@ class context_base { self_->conn_->set_rpc_call_type( coro_connection::rpc_call_type::callback_with_delay); } - - template - void set_tag(T &&tag) { - self_->conn_->set_tag(std::forward(tag)); - } - - std::any get_tag() { return self_->conn_->get_tag(); } + std::any &tag() { return self_->conn_->tag(); } + const std::any &tag() const { return self_->conn_->tag(); } }; template diff --git a/include/ylt/coro_rpc/impl/coro_connection.hpp b/include/ylt/coro_rpc/impl/coro_connection.hpp index a18be38c7..349d20479 100644 --- a/include/ylt/coro_rpc/impl/coro_connection.hpp +++ b/include/ylt/coro_rpc/impl/coro_connection.hpp @@ -315,8 +315,8 @@ class coro_connection : public std::enable_shared_from_this { return {}; }; std::string body_buf; - std::string header_buf = - rpc_protocol::prepare_response(body_buf, req_head, 0, ec, error_msg); + std::string header_buf = rpc_protocol::prepare_response( + body_buf, req_head, 0, ec, error_msg, true); response(std::move(header_buf), std::move(body_buf), std::move(attach_ment), shared_from_this(), is_delay) .via(executor_) @@ -356,12 +356,8 @@ class coro_connection : public std::enable_shared_from_this { conn_id_ = conn_id; } - template - void set_tag(T &&tag) { - tag_ = std::forward(tag); - } - - std::any get_tag() { return tag_; } + std::any &tag() { return tag_; } + const std::any &tag() const { return tag_; } auto &get_executor() { return *executor_; } diff --git a/include/ylt/coro_rpc/impl/coro_rpc_client.hpp b/include/ylt/coro_rpc/impl/coro_rpc_client.hpp index a5e6c5fdb..0cace0822 100644 --- a/include/ylt/coro_rpc/impl/coro_rpc_client.hpp +++ b/include/ylt/coro_rpc/impl/coro_rpc_client.hpp @@ -179,7 +179,7 @@ class coro_rpc_client { * @param timeout_duration RPC call timeout * @return error code */ - [[nodiscard]] async_simple::coro::Lazy reconnect( + [[nodiscard]] async_simple::coro::Lazy reconnect( std::string host, std::string port, std::chrono::steady_clock::duration timeout_duration = std::chrono::seconds(5)) { @@ -191,7 +191,7 @@ class coro_rpc_client { return connect(is_reconnect_t{true}); } - [[nodiscard]] async_simple::coro::Lazy reconnect( + [[nodiscard]] async_simple::coro::Lazy reconnect( std::string endpoint, std::chrono::steady_clock::duration timeout_duration = std::chrono::seconds(5)) { @@ -214,7 +214,7 @@ class coro_rpc_client { * @param timeout_duration RPC call timeout * @return error code */ - [[nodiscard]] async_simple::coro::Lazy connect( + [[nodiscard]] async_simple::coro::Lazy connect( std::string host, std::string port, std::chrono::steady_clock::duration timeout_duration = std::chrono::seconds(5)) { @@ -224,7 +224,7 @@ class coro_rpc_client { std::chrono::duration_cast(timeout_duration); return connect(); } - [[nodiscard]] async_simple::coro::Lazy connect( + [[nodiscard]] async_simple::coro::Lazy connect( std::string_view endpoint, std::chrono::steady_clock::duration timeout_duration = std::chrono::seconds(5)) { @@ -389,8 +389,8 @@ class coro_rpc_client { is_timeout_ = false; has_closed_ = false; } - static bool is_ok(coro_rpc::errc ec) noexcept { return !ec; } - [[nodiscard]] async_simple::coro::Lazy connect( + static bool is_ok(coro_rpc::err_code ec) noexcept { return !ec; } + [[nodiscard]] async_simple::coro::Lazy connect( is_reconnect_t is_reconnect = is_reconnect_t{false}) { #ifdef YLT_ENABLE_SSL if (!ssl_init_ret_) { @@ -447,7 +447,7 @@ class coro_rpc_client { } #endif - co_return coro_rpc::errc{}; + co_return coro_rpc::err_code{}; }; #ifdef YLT_ENABLE_SSL [[nodiscard]] bool init_ssl_impl() { @@ -664,9 +664,9 @@ class coro_rpc_client { file << resp_attachment_buf_; file.close(); #endif - r = handle_response_buffer(read_buf_, - coro_rpc::errc{header.err_code}); - if (!r) { + bool ec = false; + r = handle_response_buffer(read_buf_, header.err_code, ec); + if (ec) { close(); } co_return r; @@ -740,29 +740,41 @@ class coro_rpc_client { } template - rpc_result handle_response_buffer( - std::string &buffer, coro_rpc::errc rpc_errc) { + rpc_result handle_response_buffer(std::string &buffer, + uint8_t rpc_errc, + bool &error_happen) { rpc_return_type_t ret; struct_pack::errc ec; coro_rpc_protocol::rpc_error err; - if (rpc_errc == coro_rpc::errc{}) { - ec = struct_pack::deserialize_to(ret, buffer); - if (ec == struct_pack::errc::ok) { - if constexpr (std::is_same_v) { - return {}; - } - else { - return std::move(ret); + if (rpc_errc == 0) + AS_LIKELY { + ec = struct_pack::deserialize_to(ret, buffer); + if (ec == struct_pack::errc::ok) { + if constexpr (std::is_same_v) { + return {}; + } + else { + return std::move(ret); + } } } - } else { err.code = rpc_errc; - ec = struct_pack::deserialize_to(err.msg, buffer); - if (ec == struct_pack::errc::ok) { - return rpc_result{unexpect_t{}, std::move(err)}; + if (rpc_errc != UINT8_MAX) { + ec = struct_pack::deserialize_to(err.msg, buffer); + if (ec == struct_pack::errc::ok) { + error_happen = true; + return rpc_result{unexpect_t{}, std::move(err)}; + } + } + else { + ec = struct_pack::deserialize_to(err, buffer); + if (ec == struct_pack::errc::ok) { + return rpc_result{unexpect_t{}, std::move(err)}; + } } } + error_happen = true; // deserialize failed. err = {errc::invalid_argument, "failed to deserialize rpc return value"}; return rpc_result{unexpect_t{}, std::move(err)}; @@ -807,8 +819,8 @@ class coro_rpc_client { #ifdef UNIT_TEST_INJECT public: - coro_rpc::errc sync_connect(const std::string &host, - const std::string &port) { + coro_rpc::err_code sync_connect(const std::string &host, + const std::string &port) { return async_simple::coro::syncAwait(connect(host, port)); } diff --git a/include/ylt/coro_rpc/impl/coro_rpc_server.hpp b/include/ylt/coro_rpc/impl/coro_rpc_server.hpp index f2b74ba6d..3498ede05 100644 --- a/include/ylt/coro_rpc/impl/coro_rpc_server.hpp +++ b/include/ylt/coro_rpc/impl/coro_rpc_server.hpp @@ -104,7 +104,7 @@ class coro_rpc_server_base { * * @return error code if start failed, otherwise block until server stop. */ - [[nodiscard]] coro_rpc::errc start() noexcept { + [[nodiscard]] coro_rpc::err_code start() noexcept { auto ret = async_start(); if (ret) { ret.value().wait(); @@ -115,10 +115,10 @@ class coro_rpc_server_base { } } - [[nodiscard]] coro_rpc::expected, - coro_rpc::errc> + [[nodiscard]] coro_rpc::expected, + coro_rpc::err_code> async_start() noexcept { - coro_rpc::errc ec{}; + coro_rpc::err_code ec{}; { std::unique_lock lock(start_mtx_); if (flag_ != stat::init) { @@ -128,7 +128,7 @@ class coro_rpc_server_base { else if (flag_ == stat::stop) { ELOGV(INFO, "has stoped"); } - return coro_rpc::unexpected{ + return coro_rpc::unexpected{ coro_rpc::errc::server_has_ran}; } ec = listen(); @@ -147,11 +147,11 @@ class coro_rpc_server_base { } } if (!ec) { - async_simple::Promise promise; + async_simple::Promise promise; auto future = promise.getFuture(); accept().start([p = std::move(promise)](auto &&res) mutable { if (res.hasError()) { - p.setValue(coro_rpc::errc::io_error); + p.setValue(coro_rpc::err_code{coro_rpc::errc::io_error}); } else { p.setValue(res.value()); @@ -160,7 +160,7 @@ class coro_rpc_server_base { return std::move(future); } else { - return coro_rpc::unexpected{ec}; + return coro_rpc::unexpected{ec}; } } @@ -285,7 +285,7 @@ class coro_rpc_server_base { auto &get_io_context_pool() noexcept { return pool_; } private: - coro_rpc::errc listen() { + coro_rpc::err_code listen() { ELOGV(INFO, "begin to listen"); using asio::ip::tcp; auto endpoint = tcp::endpoint(tcp::v4(), port_); @@ -319,7 +319,7 @@ class coro_rpc_server_base { return {}; } - async_simple::coro::Lazy accept() { + async_simple::coro::Lazy accept() { for (;;) { auto executor = pool_.get_executor(); asio::ip::tcp::socket socket(executor->get_asio_executor()); diff --git a/include/ylt/coro_rpc/impl/errno.h b/include/ylt/coro_rpc/impl/errno.h index 6c2f2d573..851e7f5bc 100644 --- a/include/ylt/coro_rpc/impl/errno.h +++ b/include/ylt/coro_rpc/impl/errno.h @@ -14,6 +14,8 @@ * limitations under the License. */ #include + +#include #pragma once namespace coro_rpc { enum class errc : uint16_t { @@ -27,10 +29,31 @@ enum class errc : uint16_t { interrupted, function_not_registered, protocol_error, + unknown_protocol_version, message_too_large, server_has_ran, - user_defined_err_min = 256, - user_defined_err_max = 65535 +}; +struct err_code { + public: + errc ec; + err_code() : ec(errc::ok) {} + explicit err_code(uint16_t ec) : ec{ec} {}; + err_code(errc ec) : ec(ec){}; + err_code& operator=(errc ec) { + this->ec = ec; + return *this; + } + err_code& operator=(uint16_t ec) { + this->ec = errc{ec}; + return *this; + } + err_code(const err_code& err_code) = default; + err_code& operator=(const err_code& o) = default; + bool operator!() const { return ec == errc::ok; } + operator errc() const { return ec; } + operator bool() const { return static_cast(ec); } + explicit operator uint16_t() const { return static_cast(ec); } + uint16_t val() const { return static_cast(ec); } }; inline bool operator!(errc ec) { return ec == errc::ok; } inline std::string_view make_error_message(errc ec) { diff --git a/include/ylt/coro_rpc/impl/protocol/coro_rpc_protocol.hpp b/include/ylt/coro_rpc/impl/protocol/coro_rpc_protocol.hpp index 0d90a58a7..ee20bd5b2 100644 --- a/include/ylt/coro_rpc/impl/protocol/coro_rpc_protocol.hpp +++ b/include/ylt/coro_rpc/impl/protocol/coro_rpc_protocol.hpp @@ -38,6 +38,7 @@ namespace protocol { struct coro_rpc_protocol { public: + constexpr static inline uint8_t VERSION_NUMBER = 0; /*! * RPC header * @@ -66,11 +67,11 @@ struct coro_rpc_protocol { struct resp_header { uint8_t magic; //!< magic number uint8_t version; //!< rpc protocol version - uint16_t err_code; //!< rpc error type + uint8_t err_code; //!< rpc error type + uint8_t msg_type; //!< message type uint32_t seq_num; //!< sequence number uint32_t length; //!< length of RPC body uint32_t attach_length; //!< reserved field - uint8_t msg_type; //!< message type }; using supported_serialize_protocols = std::variant; @@ -98,7 +99,8 @@ struct coro_rpc_protocol { socket, asio::buffer((char*)&req_head, sizeof(req_header))); if (ec) AS_UNLIKELY { co_return std::move(ec); } - else if (req_head.magic != magic_number) + else if (req_head.magic != magic_number || + req_head.version > VERSION_NUMBER) AS_UNLIKELY { co_return std::make_error_code(std::errc::protocol_error); } co_return std::error_code{}; } @@ -131,8 +133,16 @@ struct coro_rpc_protocol { const req_header& req_header, std::size_t attachment_len, coro_rpc::errc rpc_err_code = {}, - std::string_view err_msg = {}) { + std::string_view err_msg = {}, + bool is_user_defined_error = false) { std::string err_msg_buf; + std::string header_buf; + header_buf.resize(RESP_HEAD_LEN); + auto& resp_head = *(resp_header*)header_buf.data(); + resp_head.magic = magic_number; + resp_head.version = VERSION_NUMBER; + resp_head.seq_num = req_header.seq_num; + resp_head.attach_length = attachment_len; if (attachment_len > UINT32_MAX) AS_UNLIKELY { ELOGV(ERROR, "attachment larger than 4G:%d", attachment_len); @@ -140,6 +150,7 @@ struct coro_rpc_protocol { err_msg_buf = "attachment larger than 4G:" + std::to_string(attachment_len) + "B"; err_msg = err_msg_buf; + is_user_defined_error = false; } else if (rpc_result.size() > UINT32_MAX) AS_UNLIKELY { @@ -149,18 +160,21 @@ struct coro_rpc_protocol { err_msg_buf = "body larger than 4G:" + std::to_string(attachment_len) + "B"; err_msg = err_msg_buf; + is_user_defined_error = false; } - std::string header_buf; - header_buf.resize(RESP_HEAD_LEN); - auto& resp_head = *(resp_header*)header_buf.data(); - resp_head.magic = magic_number; - resp_head.seq_num = req_header.seq_num; - resp_head.err_code = static_cast(rpc_err_code); - resp_head.attach_length = attachment_len; if (rpc_err_code != coro_rpc::errc{}) AS_UNLIKELY { rpc_result.clear(); - struct_pack::serialize_to(rpc_result, err_msg); + if (is_user_defined_error) { + struct_pack::serialize_to( + rpc_result, + std::pair{static_cast(rpc_err_code), err_msg}); + resp_head.err_code = static_cast(255); + } + else { + struct_pack::serialize_to(rpc_result, err_msg); + resp_head.err_code = static_cast(rpc_err_code); + } } resp_head.length = rpc_result.size(); return header_buf; @@ -169,11 +183,14 @@ struct coro_rpc_protocol { /*! * The RPC error for client * - * The `rpc_error` struct holds the error code `code` and error message `msg`. + * The `rpc_error` struct holds the error code `code` and error message + * `msg`. */ struct rpc_error { - coro_rpc::errc code; //!< error code - std::string msg; //!< error message + coro_rpc::err_code code; //!< error code + std::string msg; //!< error message + uint16_t& val() { return *(uint16_t*)&(code.ec); } + const uint16_t& val() const { return *(uint16_t*)&(code.ec); } }; // internal variable @@ -183,10 +200,13 @@ struct coro_rpc_protocol { static_assert(REQ_HEAD_LEN == 20); static constexpr auto RESP_HEAD_LEN = sizeof(resp_header{}); - static_assert(RESP_HEAD_LEN == 20); + static_assert(RESP_HEAD_LEN == 16); }; + +STRUCT_PACK_REFL(coro_rpc_protocol::rpc_error, val(), msg); } // namespace protocol template using context = coro_rpc::context_base; +using rpc_error = protocol::coro_rpc_protocol::rpc_error; } // namespace coro_rpc \ No newline at end of file diff --git a/src/coro_io/tests/test_client_pool.cpp b/src/coro_io/tests/test_client_pool.cpp index 24986ca78..684fc5dca 100644 --- a/src/coro_io/tests/test_client_pool.cpp +++ b/src/coro_io/tests/test_client_pool.cpp @@ -159,7 +159,7 @@ struct mock_client : public coro_rpc::coro_rpc_client { async_simple::coro::Lazy reconnect( const std::string &hostname) { auto ec = co_await this->coro_rpc::coro_rpc_client::reconnect(hostname); - if (!!ec) { + if (ec) { co_await coro_io::sleep_for(300ms); } co_return ec; diff --git a/src/coro_rpc/examples/base_examples/client.cpp b/src/coro_rpc/examples/base_examples/client.cpp index 306fbd215..efdf03833 100644 --- a/src/coro_rpc/examples/base_examples/client.cpp +++ b/src/coro_rpc/examples/base_examples/client.cpp @@ -31,67 +31,53 @@ Lazy show_rpc_call() { assert(!ec); auto ret = co_await client.call(); - if (!ret) { - std::cout << "hello_world err: " << ret.error().msg << std::endl; - } assert(ret.value() == "hello_world"s); client.set_req_attachment("This is attachment."); auto ret_void = co_await client.call(); - if (!ret) { - std::cout << "hello_world err: " << ret.error().msg << std::endl; - } assert(client.get_resp_attachment() == "This is attachment."); client.set_req_attachment("This is attachment2."); ret_void = co_await client.call(); - if (!ret) { - std::cout << "hello_world err: " << ret.error().msg << std::endl; - } assert(client.get_resp_attachment() == "This is attachment2."); auto ret_int = co_await client.call(12, 30); - if (!ret_int) { - std::cout << "A_add_B err: " << ret_int.error().msg << std::endl; - } assert(ret_int.value() == 42); ret = co_await client.call("coro_echo"); - if (!ret) { - std::cout << "coro_echo err: " << ret.error().msg << std::endl; - } assert(ret.value() == "coro_echo"s); ret = co_await client.call("hello_with_delay"s); - if (!ret) { - std::cout << "hello_with_delay err: " << ret.error().msg << std::endl; - } assert(ret.value() == "hello_with_delay"s); ret = co_await client.call("nested_echo"s); - if (!ret) { - std::cout << "nested_echo err: " << ret.error().msg << std::endl; - } assert(ret.value() == "nested_echo"s); ret = co_await client.call<&HelloService::hello>(); - if (!ret) { - std::cout << "HelloService::hello err: " << ret.error().msg << std::endl; - } assert(ret.value() == "HelloService::hello"s); ret = co_await client.call<&HelloService::hello_with_delay>( "HelloService::hello_with_delay"s); - if (!ret) { - std::cout << "HelloService::hello_with_delay err: " << ret.error().msg - << std::endl; - } assert(ret.value() == "HelloService::hello_with_delay"s); + + ret = co_await client.call(); + assert(ret.error().code = 404); + assert(ret.error().msg == "404 Not Found."); + + ret = co_await client.call(); + assert(ret.value() == "1"); + ret = co_await client.call(); + assert(ret.value() == "2"); + ret = co_await client.call(); + assert(ret.value() == "3"); } int main() { - syncAwait(show_rpc_call()); - - std::cout << "Done!" << std::endl; + try { + syncAwait(show_rpc_call()); + std::cout << "Done!" << std::endl; + } catch (const std::exception& e) { + std::cout << "Error:" << e.what() << std::endl; + } return 0; } \ No newline at end of file diff --git a/src/coro_rpc/examples/base_examples/rpc_service.cpp b/src/coro_rpc/examples/base_examples/rpc_service.cpp index 24a2e5e14..e85d8ca95 100644 --- a/src/coro_rpc/examples/base_examples/rpc_service.cpp +++ b/src/coro_rpc/examples/base_examples/rpc_service.cpp @@ -16,10 +16,13 @@ #include "rpc_service.h" #include +#include #include #include #include +#include "ylt/coro_rpc/impl/errno.h" + using namespace coro_rpc; std::string hello_world() { @@ -97,3 +100,15 @@ void HelloService::hello_with_delay( }).detach(); return; } + +void return_error(coro_rpc::context conn) { + conn.response_error(coro_rpc::err_code{404}, "404 Not Found."); +} +void rpc_with_state_by_tag(coro_rpc::context conn) { + if (!conn.tag().has_value()) { + conn.tag() = uint64_t{0}; + } + auto &cnter = std::any_cast(conn.tag()); + ELOGV(INFO, "call count: %d", ++cnter); + conn.response_msg(std::to_string(cnter)); +} \ No newline at end of file diff --git a/src/coro_rpc/examples/base_examples/rpc_service.h b/src/coro_rpc/examples/base_examples/rpc_service.h index 897d6f287..145dfe1bd 100644 --- a/src/coro_rpc/examples/base_examples/rpc_service.h +++ b/src/coro_rpc/examples/base_examples/rpc_service.h @@ -26,6 +26,8 @@ void hello_with_delay(coro_rpc::context conn, std::string hello); std::string echo(std::string_view sv); void echo_with_attachment(coro_rpc::context conn); void echo_with_attachment2(coro_rpc::context conn); +void return_error(coro_rpc::context conn); +void rpc_with_state_by_tag(coro_rpc::context conn); async_simple::coro::Lazy coro_echo(std::string_view sv); async_simple::coro::Lazy nested_echo(std::string_view sv); class HelloService { diff --git a/src/coro_rpc/examples/base_examples/server.cpp b/src/coro_rpc/examples/base_examples/server.cpp index 80b435c29..5efb49d4a 100644 --- a/src/coro_rpc/examples/base_examples/server.cpp +++ b/src/coro_rpc/examples/base_examples/server.cpp @@ -29,7 +29,8 @@ int main() { // regist normal function for rpc server.register_handler(); + echo_with_attachment2, return_error, + rpc_with_state_by_tag>(); // regist member function for rpc HelloService hello_service; diff --git a/src/coro_rpc/examples/file_transfer/rpc_service.cpp b/src/coro_rpc/examples/file_transfer/rpc_service.cpp index 8fbde11b3..e375fc2b2 100644 --- a/src/coro_rpc/examples/file_transfer/rpc_service.cpp +++ b/src/coro_rpc/examples/file_transfer/rpc_service.cpp @@ -1,28 +1,23 @@ #include "rpc_service.h" #include +#include std::string echo(std::string str) { return str; } void upload_file(coro_rpc::context conn, file_part part) { - std::shared_ptr stream = nullptr; - if (!conn.get_tag().has_value()) { - stream = std::make_shared(); + if (!conn.tag().has_value()) { auto filename = std::to_string(std::time(0)) + std::filesystem::path(part.filename).extension().string(); - stream->open(filename, std::ios::binary | std::ios::app); - conn.set_tag(stream); + conn.tag() = std::make_shared( + filename, std::ios::binary | std::ios::app); } - else { - stream = std::any_cast>(conn.get_tag()); - } - + auto stream = std::any_cast>(conn.tag()); std::cout << "file part content size=" << part.content.size() << "\n"; - stream->write(part.content.data(), part.content.size()); if (part.eof) { stream->close(); - conn.set_tag(std::any{}); + conn.tag().reset(); std::cout << "file upload finished\n"; } @@ -31,8 +26,7 @@ void upload_file(coro_rpc::context conn, file_part part) { void download_file(coro_rpc::context conn, std::string filename) { - std::shared_ptr stream = nullptr; - if (!conn.get_tag().has_value()) { + if (!conn.tag().has_value()) { std::string actual_filename = std::filesystem::path(filename).filename().string(); if (!std::filesystem::is_regular_file(actual_filename) || @@ -40,13 +34,10 @@ void download_file(coro_rpc::context conn, conn.response_msg(response_part{std::errc::invalid_argument}); return; } - - stream = std::make_shared(actual_filename, std::ios::binary); - conn.set_tag(stream); - } - else { - stream = std::any_cast>(conn.get_tag()); + conn.tag() = + std::make_shared(actual_filename, std::ios::binary); } + auto stream = std::any_cast>(conn.tag()); char buf[1024]; @@ -56,7 +47,7 @@ void download_file(coro_rpc::context conn, if (stream->eof()) { stream->close(); - conn.set_tag(std::any{}); + conn.tag().reset(); } } diff --git a/src/coro_rpc/tests/ServerTester.hpp b/src/coro_rpc/tests/ServerTester.hpp index 97682fec2..606be2e35 100644 --- a/src/coro_rpc/tests/ServerTester.hpp +++ b/src/coro_rpc/tests/ServerTester.hpp @@ -374,7 +374,7 @@ struct ServerTester : TesterConfig { auto client2 = init_client(); ec = syncAwait(client2->connect("10.255.255.1", port_, 5ms)); CHECK_MESSAGE( - !!ec, + ec, std::to_string(client->get_client_id()).append(make_error_message(ec))); } diff --git a/src/coro_rpc/tests/rpc_api.hpp b/src/coro_rpc/tests/rpc_api.hpp index a987a9782..66fca1981 100644 --- a/src/coro_rpc/tests/rpc_api.hpp +++ b/src/coro_rpc/tests/rpc_api.hpp @@ -19,6 +19,8 @@ #include #include +#include "ylt/coro_rpc/impl/errno.h" + void hi(); std::string hello(); std::string hello_timeout(); @@ -35,7 +37,7 @@ struct my_context { }; void echo_with_attachment(coro_rpc::context conn); inline void error_with_context(coro_rpc::context conn) { - conn.response_error(coro_rpc::errc{104}, "My Error."); + conn.response_error(coro_rpc::err_code{104}, "My Error."); } void coro_fun_with_user_define_connection_type(my_context conn); void coro_fun_with_delay_return_void(coro_rpc::context conn); diff --git a/src/coro_rpc/tests/test_coro_rpc_client.cpp b/src/coro_rpc/tests/test_coro_rpc_client.cpp index 73a132c10..e3da3b7ae 100644 --- a/src/coro_rpc/tests/test_coro_rpc_client.cpp +++ b/src/coro_rpc/tests/test_coro_rpc_client.cpp @@ -289,7 +289,7 @@ class SSLClientTester { auto f = [this, &client]() -> Lazy { auto ec = co_await client->connect("127.0.0.1", port_); if (server_crt == ssl_type::_ && server_key == ssl_type::_) { - if (!!ec) { + if (ec) { ELOGV(INFO, "%s", gen_err().data()); } REQUIRE_MESSAGE(!ec, make_error_message(ec)); @@ -419,11 +419,15 @@ TEST_CASE("testing client with context response user-defined error") { coro_rpc_client client(*coro_io::get_global_executor(), g_client_id++); auto ec = client.sync_connect("127.0.0.1", "8801"); REQUIRE(!ec); - server.register_handler(); + server.register_handler(); auto ret = client.sync_call(); - CHECK(!ret.has_value()); + REQUIRE(!ret.has_value()); CHECK(ret.error().code == coro_rpc::errc{104}); CHECK(ret.error().msg == "My Error."); + CHECK(client.has_closed() == false); + auto ret2 = client.sync_call(); + REQUIRE(ret2.has_value()); + CHECK(ret2.value() == "hello"); } TEST_CASE("testing client with shutdown") {