Skip to content

Commit 0d86235

Browse files
authored
[coro_http_client]add error code (#921)
1 parent 53ab3c3 commit 0d86235

File tree

5 files changed

+84
-19
lines changed

5 files changed

+84
-19
lines changed

include/ylt/standalone/cinatra/coro_http_client.hpp

+17-16
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "brzip.hpp"
3131
#endif
3232
#include "cinatra_log_wrapper.hpp"
33+
#include "error.hpp"
3334
#include "http_parser.hpp"
3435
#include "multipart.hpp"
3536
#include "picohttpparser.h"
@@ -355,7 +356,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
355356
data = co_await connect(u);
356357
}
357358
if (socket_->is_timeout_) {
358-
co_return resp_data{std::make_error_code(std::errc::timed_out), 404};
359+
co_return resp_data{make_error_code(http_errc::connect_timeout), 404};
359360
}
360361
if (!data.net_err) {
361362
data.status = 200;
@@ -715,7 +716,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
715716
data = co_await connect(u);
716717
}
717718
if (socket_->is_timeout_) {
718-
co_return resp_data{std::make_error_code(std::errc::timed_out), 404};
719+
co_return resp_data{make_error_code(http_errc::connect_timeout), 404};
719720
}
720721
if (data.net_err) {
721722
co_return data;
@@ -743,7 +744,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
743744

744745
if (data.net_err) {
745746
if (socket_->is_timeout_) {
746-
data.net_err = std::make_error_code(std::errc::timed_out);
747+
data.net_err = make_error_code(http_errc::request_timeout);
747748
}
748749
co_return data;
749750
}
@@ -754,7 +755,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
754755
if (std::tie(ec, size) = co_await async_write(asio::buffer(last_part));
755756
ec) {
756757
if (socket_->is_timeout_) {
757-
ec = std::make_error_code(std::errc::timed_out);
758+
ec = make_error_code(http_errc::request_timeout);
758759
}
759760
co_return resp_data{ec, 404};
760761
}
@@ -763,7 +764,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
763764
data = co_await handle_read(ec, size, is_keep_alive, std::move(ctx),
764765
http_method::POST);
765766
if (socket_->is_timeout_) {
766-
ec = std::make_error_code(std::errc::timed_out);
767+
ec = make_error_code(http_errc::request_timeout);
767768
}
768769
handle_result(data, ec, is_keep_alive);
769770
co_return data;
@@ -1097,7 +1098,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
10971098
data = co_await connect(u);
10981099
}
10991100
if (socket_->is_timeout_) {
1100-
co_return resp_data{std::make_error_code(std::errc::timed_out), 404};
1101+
co_return resp_data{make_error_code(http_errc::connect_timeout), 404};
11011102
}
11021103
if (data.net_err) {
11031104
co_return data;
@@ -1108,7 +1109,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
11081109
std::tie(ec, size) = co_await async_write(asio::buffer(header_str));
11091110
if (ec) {
11101111
if (socket_->is_timeout_) {
1111-
ec = std::make_error_code(std::errc::timed_out);
1112+
ec = make_error_code(http_errc::request_timeout);
11121113
}
11131114
co_return resp_data{ec, 404};
11141115
}
@@ -1179,15 +1180,15 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
11791180
}
11801181
if (ec) {
11811182
if (socket_->is_timeout_) {
1182-
ec = std::make_error_code(std::errc::timed_out);
1183+
ec = make_error_code(http_errc::request_timeout);
11831184
}
11841185
co_return resp_data{ec, 404};
11851186
}
11861187

11871188
data = co_await handle_read(ec, size, is_keep_alive, std::move(ctx),
11881189
http_method::POST);
11891190
if (ec && socket_->is_timeout_) {
1190-
ec = std::make_error_code(std::errc::timed_out);
1191+
ec = make_error_code(http_errc::request_timeout);
11911192
}
11921193
handle_result(data, ec, is_keep_alive);
11931194
co_return data;
@@ -1253,7 +1254,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
12531254
data = co_await connect(u);
12541255
}
12551256
if (socket_->is_timeout_) {
1256-
co_return resp_data{std::make_error_code(std::errc::timed_out), 404};
1257+
co_return resp_data{make_error_code(http_errc::connect_timeout), 404};
12571258
}
12581259
if (data.net_err) {
12591260
co_return data;
@@ -1264,7 +1265,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
12641265
std::tie(ec, size) = co_await async_write(asio::buffer(header_str));
12651266
if (ec) {
12661267
if (socket_->is_timeout_) {
1267-
ec = std::make_error_code(std::errc::timed_out);
1268+
ec = make_error_code(http_errc::request_timeout);
12681269
}
12691270
co_return resp_data{ec, 404};
12701271
}
@@ -1319,15 +1320,15 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
13191320
}
13201321
if (ec) {
13211322
if (socket_->is_timeout_) {
1322-
ec = std::make_error_code(std::errc::timed_out);
1323+
ec = make_error_code(http_errc::request_timeout);
13231324
}
13241325
co_return resp_data{ec, 404};
13251326
}
13261327

13271328
data = co_await handle_read(ec, size, is_keep_alive, std::move(ctx),
13281329
http_method::POST);
13291330
if (ec && socket_->is_timeout_) {
1330-
ec = std::make_error_code(std::errc::timed_out);
1331+
ec = make_error_code(http_errc::request_timeout);
13311332
}
13321333
handle_result(data, ec, is_keep_alive);
13331334
co_return data;
@@ -1397,7 +1398,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
13971398
}
13981399

13991400
if (socket_->is_timeout_) {
1400-
data.net_err = std::make_error_code(std::errc::timed_out);
1401+
data.net_err = make_error_code(http_errc::connect_timeout);
14011402
co_return data;
14021403
}
14031404

@@ -1460,7 +1461,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
14601461
co_await handle_read(ec, size, is_keep_alive, std::move(ctx), method);
14611462
} while (0);
14621463
if (ec && socket_->is_timeout_) {
1463-
ec = std::make_error_code(std::errc::timed_out);
1464+
ec = make_error_code(http_errc::request_timeout);
14641465
}
14651466
handle_result(data, ec, is_keep_alive);
14661467
co_return data;
@@ -2086,7 +2087,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
20862087
}
20872088

20882089
if (socket_->is_timeout_) {
2089-
auto ec = std::make_error_code(std::errc::timed_out);
2090+
auto ec = make_error_code(http_errc::connect_timeout);
20902091
co_return resp_data{ec, 404};
20912092
}
20922093

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#pragma once
2+
#include <string>
3+
#include <system_error>
4+
5+
namespace cinatra {
6+
enum class http_errc { connect_timeout = 2025, request_timeout };
7+
8+
class http_error_category : public std::error_category {
9+
public:
10+
const char* name() const noexcept override { return "coro_http_error"; }
11+
12+
std::string message(int ev) const override {
13+
switch (static_cast<http_errc>(ev)) {
14+
case http_errc::connect_timeout:
15+
return "Connect timeout";
16+
case http_errc::request_timeout:
17+
return "Request timeout";
18+
default:
19+
return "Unknown error";
20+
}
21+
}
22+
};
23+
24+
inline cinatra::http_error_category& category() {
25+
static cinatra::http_error_category instance;
26+
return instance;
27+
}
28+
29+
inline std::error_code make_error_code(http_errc e) {
30+
return {static_cast<int>(e), category()};
31+
}
32+
33+
inline bool operator==(const std::error_code& code, http_errc ec) {
34+
return code.value() == (int)ec;
35+
}
36+
37+
} // namespace cinatra

src/coro_http/tests/test_cinatra.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -1914,13 +1914,15 @@ TEST_CASE("test coro_http_client chunked upload and download") {
19141914
result = async_simple::coro::syncAwait(client.async_upload_chunked(
19151915
uri, http_method::PUT, "chunked_file.txt"sv));
19161916
CHECK(result.status != 200);
1917+
CHECK(result.net_err == http_errc::connect_timeout);
19171918

19181919
client.set_conn_timeout(500ms);
19191920
client.set_req_timeout(0ms);
19201921
client.add_header("filename", "chunked_file.txt");
19211922
result = async_simple::coro::syncAwait(client.async_upload_chunked(
19221923
uri, http_method::PUT, "chunked_file.txt"sv));
19231924
CHECK(result.status != 200);
1925+
CHECK(result.net_err == http_errc::request_timeout);
19241926

19251927
fs::remove("chunked_file.txt");
19261928
}
@@ -2134,7 +2136,7 @@ TEST_CASE("test coro_http_client request timeout") {
21342136
if (!r.net_err) {
21352137
r = async_simple::coro::syncAwait(client.async_get("/"));
21362138
if (r.net_err) {
2137-
CHECK(r.net_err == std::errc::timed_out);
2139+
CHECK(r.net_err == http_errc::request_timeout);
21382140
}
21392141
}
21402142
}
@@ -2280,7 +2282,7 @@ TEST_CASE("test coro http request timeout") {
22802282

22812283
client.set_req_timeout(500ms);
22822284
result = async_simple::coro::syncAwait(client.async_get(uri));
2283-
CHECK(result.net_err == std::errc::timed_out);
2285+
CHECK(result.net_err == http_errc::request_timeout);
22842286

22852287
// after timeout, the socket in client has been closed, so use a new client
22862288
// to test.

src/coro_http/tests/test_mixed.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,6 @@ TEST_CASE("test parallel http request") {
262262
}
263263
else {
264264
g_failed_count++;
265-
CHECK(result.net_err == std::errc::timed_out);
266265
CINATRA_LOG_INFO << result.status << ", "
267266
<< result.net_err.value() << ", "
268267
<< result.net_err.message();

website/docs/zh/coro_http/coro_http_introduction.md

+26
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,32 @@ websocket 例子:
479479
CHECK(data.resp_body == send_str);
480480
```
481481
482+
## 错误码
483+
coro_http 错误码复用了std::error_code,具体错误的值为std::errc:https://en.cppreference.com/w/cpp/error/errc
484+
485+
coro_http 只对std::errc::timeout错误码做了扩展,发生连接和请求超时的时候不会返回有二义性的std::errc::timeout,而是返回扩展的http_errc:
486+
```cpp
487+
enum class http_errc { connect_timeout = 2025, request_timeout };
488+
std::error_code make_error_code(http_errc e);
489+
```
490+
error message 分别对应:`Connect timeout``Request timeout`
491+
492+
常见的返回错误及其含义有:
493+
494+
std::errc::protocol_error: url解析错误;response 解析错误;websocket 协议解析错误;chunked格式解析错误;gzip解析错误都归为协议错误;
495+
496+
http_errc::connect_timeout:连接超时,自定义错误码2025,错误消息`Connect timeout`
497+
498+
http_errc::request_timeout:请求超时,自定义错误码2026,错误消息`Request timeout`
499+
500+
std::errc::invalid_argument:请求参数非法,文件上传时文件不存在;文件上传时upload size非法;
501+
502+
std::errc::bad_file_descriptor:文件流上传时,文件打开失败;
503+
504+
std::errc::no_such_file_or_directory:文件流发送时文件不存在
505+
506+
网络io返回的错误来自于asio io请求返回的错误asio::error(std::errc 的子集),如asio::error::eof, asio::error::broken_pipe,asio::connection_reset,asio::error::connection_refused等等;
507+
482508
## 线程模型
483509
coro_http_client 默认情况下是共享一个全局“线程池”,这个“线程池”准确来说是一个io_context pool,coro_http_client 的线程模型是一个client一个io_context,
484510
io_context 和 client 是一对多的关系。io_context pool 默认的线程数是机器的核数,如果希望控制pool 的线程数可以调用coro_io::get_global_executor(pool_size) 去设置

0 commit comments

Comments
 (0)