Skip to content

Commit a5c8610

Browse files
committed
Uses system::result to implement per request error handling.
1 parent 3a44450 commit a5c8610

36 files changed

+885
-460
lines changed

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,15 @@ if (MSVC)
275275
target_compile_definitions(test_conn_exec_cancel PRIVATE _WIN32_WINNT=0x0601)
276276
endif()
277277

278+
add_executable(test_conn_exec_error tests/conn_exec_error.cpp)
279+
target_compile_features(test_conn_exec_error PUBLIC cxx_std_17)
280+
target_link_libraries(test_conn_exec_error common)
281+
add_test(test_conn_exec_error test_conn_exec_error)
282+
if (MSVC)
283+
target_compile_options(test_conn_exec_error PRIVATE /bigobj)
284+
target_compile_definitions(test_conn_exec_error PRIVATE _WIN32_WINNT=0x0601)
285+
endif()
286+
278287
add_executable(test_conn_echo_stress tests/conn_echo_stress.cpp)
279288
target_compile_features(test_conn_echo_stress PUBLIC cxx_std_20)
280289
target_link_libraries(test_conn_echo_stress common)

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,10 @@ Acknowledgement to people that helped shape Boost.Redis
870870
* Adds new typedef `boost::redis::generic_response` that should be used instead of `std::vector<resp3::node<std::string>>`.
871871
* Renames `redis::ignore` to `redis::ignore_t`.
872872
* Changes the signature from `async_exec` to receive a `redis::response` instead of an adapter.
873+
* Adds `boost::redis::adapter::result` to store responses to commands
874+
including possible resp3 errors without losing the error diagnostic
875+
part. Basicaly instead of accessing values as `std::get<N>(resp)`
876+
users have to type `std::get<N>(resp).value()`
873877

874878
### v1.4.0-1
875879

examples/cpp17_intro.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace redis = boost::redis;
1414
using redis::operation;
1515
using redis::request;
1616
using redis::response;
17+
using redis::ignore_t;
1718

1819
void log(boost::system::error_code const& ec, char const* prefix)
1920
{
@@ -38,7 +39,7 @@ auto main(int argc, char * argv[]) -> int
3839
req.push("QUIT");
3940

4041
// The response.
41-
response<redis::ignore_t, std::string, redis::ignore_t> resp;
42+
response<ignore_t, std::string, ignore_t> resp;
4243

4344
net::io_context ioc;
4445

@@ -64,7 +65,7 @@ auto main(int argc, char * argv[]) -> int
6465
return log(ec, "on_exec: ");
6566
}
6667

67-
std::cout << "PING: " << std::get<1>(resp) << std::endl;
68+
std::cout << "PING: " << std::get<1>(resp).value() << std::endl;
6869
};
6970

7071
// Connect callback.

examples/cpp17_intro_sync.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
#include <boost/redis/src.hpp>
1616

1717
namespace net = boost::asio;
18-
namespace redis = boost::redis;
19-
using connection = redis::connection;
18+
using connection = boost::redis::connection;
2019
using boost::redis::request;
2120
using boost::redis::response;
21+
using boost::redis::ignore_t;
2222

2323
template <class Response>
2424
auto exec(std::shared_ptr<connection> conn, request const& req, Response& resp)
@@ -66,12 +66,12 @@ auto main(int argc, char * argv[]) -> int
6666
req.push("PING");
6767
req.push("QUIT");
6868

69-
response<boost::redis::ignore_t, std::string, boost::redis::ignore_t> resp;
69+
response<ignore_t, std::string, ignore_t> resp;
7070

7171
// Executes commands synchronously.
7272
exec(conn, req, resp);
7373

74-
std::cout << "Response: " << std::get<1>(resp) << std::endl;
74+
std::cout << "Response: " << std::get<1>(resp).value() << std::endl;
7575

7676
t.join();
7777
} catch (std::exception const& e) {

examples/cpp17_low_level_sync.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
#include <boost/redis/src.hpp>
1313

1414
namespace net = boost::asio;
15-
namespace redis = boost::redis;
16-
namespace resp3 = redis::resp3;
17-
using redis::adapter::adapt2;
15+
namespace resp3 = boost::redis::resp3;
16+
using boost::redis::adapter::adapt2;
1817
using boost::redis::request;
18+
using boost::redis::adapter::result;
1919

2020
auto main(int argc, char * argv[]) -> int
2121
{
@@ -41,16 +41,16 @@ auto main(int argc, char * argv[]) -> int
4141
req.push("QUIT");
4242
resp3::write(socket, req);
4343

44-
// Responses
45-
std::string buffer, resp;
44+
std::string buffer;
45+
result<std::string> resp;
4646

4747
// Reads the responses to all commands in the request.
4848
auto dbuffer = net::dynamic_buffer(buffer);
4949
resp3::read(socket, dbuffer);
5050
resp3::read(socket, dbuffer, adapt2(resp));
5151
resp3::read(socket, dbuffer);
5252

53-
std::cout << "Ping: " << resp << std::endl;
53+
std::cout << "Ping: " << resp.value() << std::endl;
5454

5555
} catch (std::exception const& e) {
5656
std::cerr << e.what() << std::endl;

examples/cpp20_chat_room.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ auto receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
2929
{
3030
for (generic_response resp;;) {
3131
co_await conn->async_receive(resp);
32-
std::cout << resp.at(1).value << " " << resp.at(2).value << " " << resp.at(3).value << std::endl;
33-
resp.clear();
32+
std::cout << resp.value().at(1).value << " " << resp.value().at(2).value << " " << resp.value().at(3).value << std::endl;
33+
resp.value().clear();
3434
}
3535
}
3636

examples/cpp20_containers.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace redis = boost::redis;
1818
using namespace net::experimental::awaitable_operators;
1919
using boost::redis::request;
2020
using boost::redis::response;
21+
using boost::redis::ignore_t;
2122

2223
void print(std::map<std::string, std::string> const& cont)
2324
{
@@ -62,12 +63,12 @@ auto hgetall(std::shared_ptr<connection> conn) -> net::awaitable<void>
6263
req.push("HGETALL", "hset-key");
6364

6465
// Responses as tuple elements.
65-
response<redis::ignore_t, std::map<std::string, std::string>> resp;
66+
response<ignore_t, std::map<std::string, std::string>> resp;
6667

6768
// Executes the request and reads the response.
6869
co_await conn->async_exec(req, resp);
6970

70-
print(std::get<1>(resp));
71+
print(std::get<1>(resp).value());
7172
}
7273

7374
// Retrieves in a transaction.
@@ -81,17 +82,17 @@ auto transaction(std::shared_ptr<connection> conn) -> net::awaitable<void>
8182
req.push("EXEC");
8283

8384
response<
84-
redis::ignore_t, // hello
85-
redis::ignore_t, // multi
86-
redis::ignore_t, // lrange
87-
redis::ignore_t, // hgetall
85+
ignore_t, // hello
86+
ignore_t, // multi
87+
ignore_t, // lrange
88+
ignore_t, // hgetall
8889
response<std::optional<std::vector<int>>, std::optional<std::map<std::string, std::string>>> // exec
8990
> resp;
9091

9192
co_await conn->async_exec(req, resp);
9293

93-
print(std::get<0>(std::get<4>(resp)).value());
94-
print(std::get<1>(std::get<4>(resp)).value());
94+
print(std::get<0>(std::get<4>(resp).value()).value().value());
95+
print(std::get<1>(std::get<4>(resp).value()).value().value());
9596
}
9697

9798
auto quit(std::shared_ptr<connection> conn) -> net::awaitable<void>

examples/cpp20_echo_server.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ auto echo_server_session(tcp_socket socket, std::shared_ptr<connection> conn) ->
2727
auto n = co_await net::async_read_until(socket, net::dynamic_buffer(buffer, 1024), "\n");
2828
req.push("PING", buffer);
2929
co_await conn->async_exec(req, resp);
30-
co_await net::async_write(socket, net::buffer(std::get<0>(resp)));
31-
std::get<0>(resp).clear();
30+
co_await net::async_write(socket, net::buffer(std::get<0>(resp).value()));
31+
std::get<0>(resp).value().clear();
3232
req.clear();
3333
buffer.erase(0, n);
3434
}

examples/cpp20_intro.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ auto ping(std::shared_ptr<connection> conn) -> net::awaitable<void>
3636
response<std::string> resp;
3737
co_await conn->async_exec(req, resp);
3838

39-
std::cout << "PING: " << std::get<0>(resp) << std::endl;
39+
std::cout << "PING: " << std::get<0>(resp).value() << std::endl;
4040
}
4141

4242
auto quit(std::shared_ptr<connection> conn) -> net::awaitable<void>

examples/cpp20_intro_awaitable_ops.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,27 @@ namespace net = boost::asio;
1414
using namespace net::experimental::awaitable_operators;
1515
using boost::redis::request;
1616
using boost::redis::response;
17+
using boost::redis::ignore_t;
1718

1819
// Called from the main function (see main.cpp)
1920
auto co_main(std::string host, std::string port) -> net::awaitable<void>
2021
{
21-
request req;
22-
req.push("HELLO", 3);
23-
req.push("PING", "Hello world");
24-
req.push("QUIT");
22+
try {
23+
request req;
24+
req.push("HELLO", 3);
25+
req.push("PING", "Hello world");
26+
req.push("QUIT");
2527

26-
response<boost::redis::ignore_t, std::string, boost::redis::ignore_t> resp;
28+
response<ignore_t, std::string, ignore_t> resp;
2729

28-
auto conn = std::make_shared<connection>(co_await net::this_coro::executor);
29-
co_await connect(conn, host, port);
30-
co_await (conn->async_run() || conn->async_exec(req, resp));
30+
auto conn = std::make_shared<connection>(co_await net::this_coro::executor);
31+
co_await connect(conn, host, port);
32+
co_await (conn->async_run() || conn->async_exec(req, resp));
3133

32-
std::cout << "PING: " << std::get<1>(resp) << std::endl;
34+
std::cout << "PING: " << std::get<1>(resp).value() << std::endl;
35+
} catch (std::exception const& e) {
36+
std::cout << e.what() << std::endl;
37+
}
3338
}
3439

3540
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)

0 commit comments

Comments
 (0)