Skip to content

Commit 99f044e

Browse files
authored
Merge pull request #1110 from libcpr/feature/better-curl-error-code-handling
More And Better cpr Error Codes
2 parents 1d45df8 + c698b9a commit 99f044e

9 files changed

+194
-64
lines changed

cpr/error.cpp

+100-29
Original file line numberDiff line numberDiff line change
@@ -10,59 +10,130 @@ ErrorCode Error::getErrorCodeForCurlError(std::int32_t curl_code) {
1010
return ErrorCode::OK;
1111
case CURLE_UNSUPPORTED_PROTOCOL:
1212
return ErrorCode::UNSUPPORTED_PROTOCOL;
13+
case CURLE_FAILED_INIT:
14+
return ErrorCode::FAILED_INIT;
1315
case CURLE_URL_MALFORMAT:
14-
return ErrorCode::INVALID_URL_FORMAT;
16+
return ErrorCode::URL_MALFORMAT;
17+
case CURLE_NOT_BUILT_IN:
18+
return ErrorCode::NOT_BUILT_IN;
1519
case CURLE_COULDNT_RESOLVE_PROXY:
16-
return ErrorCode::PROXY_RESOLUTION_FAILURE;
20+
return ErrorCode::COULDNT_RESOLVE_PROXY;
1721
case CURLE_COULDNT_RESOLVE_HOST:
18-
return ErrorCode::HOST_RESOLUTION_FAILURE;
22+
return ErrorCode::COULDNT_RESOLVE_HOST;
1923
case CURLE_COULDNT_CONNECT:
20-
return ErrorCode::CONNECTION_FAILURE;
24+
return ErrorCode::COULDNT_CONNECT;
25+
case CURLE_WEIRD_SERVER_REPLY:
26+
return ErrorCode::WEIRD_SERVER_REPLY;
27+
case CURLE_REMOTE_ACCESS_DENIED:
28+
return ErrorCode::REMOTE_ACCESS_DENIED;
29+
case CURLE_HTTP2:
30+
return ErrorCode::HTTP2;
31+
case CURLE_QUOTE_ERROR:
32+
return ErrorCode::QUOTE_ERROR;
33+
case CURLE_HTTP_RETURNED_ERROR:
34+
return ErrorCode::HTTP_RETURNED_ERROR;
35+
case CURLE_WRITE_ERROR:
36+
return ErrorCode::WRITE_ERROR;
37+
case CURLE_UPLOAD_FAILED:
38+
return ErrorCode::UPLOAD_FAILED;
39+
case CURLE_READ_ERROR:
40+
return ErrorCode::READ_ERROR;
41+
case CURLE_OUT_OF_MEMORY:
42+
return ErrorCode::OUT_OF_MEMORY;
2143
case CURLE_OPERATION_TIMEDOUT:
2244
return ErrorCode::OPERATION_TIMEDOUT;
45+
case CURLE_RANGE_ERROR:
46+
return ErrorCode::RANGE_ERROR;
47+
case CURLE_HTTP_POST_ERROR:
48+
return ErrorCode::HTTP_POST_ERROR;
2349
case CURLE_SSL_CONNECT_ERROR:
2450
return ErrorCode::SSL_CONNECT_ERROR;
25-
#if LIBCURL_VERSION_NUM < 0x073e00
26-
case CURLE_PEER_FAILED_VERIFICATION:
27-
return ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR;
28-
#endif
51+
case CURLE_BAD_DOWNLOAD_RESUME:
52+
return ErrorCode::BAD_DOWNLOAD_RESUME;
53+
case CURLE_FILE_COULDNT_READ_FILE:
54+
return ErrorCode::FILE_COULDNT_READ_FILE;
55+
case CURLE_FUNCTION_NOT_FOUND:
56+
return ErrorCode::FUNCTION_NOT_FOUND;
2957
case CURLE_ABORTED_BY_CALLBACK:
30-
case CURLE_WRITE_ERROR:
31-
return ErrorCode::REQUEST_CANCELLED;
58+
return ErrorCode::ABORTED_BY_CALLBACK;
59+
case CURLE_BAD_FUNCTION_ARGUMENT:
60+
return ErrorCode::BAD_FUNCTION_ARGUMENT;
61+
case CURLE_INTERFACE_FAILED:
62+
return ErrorCode::INTERFACE_FAILED;
63+
case CURLE_OBSOLETE46:
64+
return ErrorCode::OBSOLETE46;
65+
case CURLE_TOO_MANY_REDIRECTS:
66+
return ErrorCode::TOO_MANY_REDIRECTS;
67+
case CURLE_UNKNOWN_OPTION:
68+
return ErrorCode::UNKNOWN_OPTION;
69+
case CURLE_SETOPT_OPTION_SYNTAX:
70+
return ErrorCode::SETOPT_OPTION_SYNTAX;
3271
case CURLE_GOT_NOTHING:
33-
return ErrorCode::EMPTY_RESPONSE;
72+
return ErrorCode::GOT_NOTHING;
3473
case CURLE_SSL_ENGINE_NOTFOUND:
74+
return ErrorCode::SSL_ENGINE_NOTFOUND;
3575
case CURLE_SSL_ENGINE_SETFAILED:
36-
return ErrorCode::GENERIC_SSL_ERROR;
76+
return ErrorCode::SSL_ENGINE_SETFAILED;
3777
case CURLE_SEND_ERROR:
38-
return ErrorCode::NETWORK_SEND_FAILURE;
78+
return ErrorCode::SEND_ERROR;
3979
case CURLE_RECV_ERROR:
40-
return ErrorCode::NETWORK_RECEIVE_ERROR;
80+
return ErrorCode::RECV_ERROR;
4181
case CURLE_SSL_CERTPROBLEM:
42-
return ErrorCode::SSL_LOCAL_CERTIFICATE_ERROR;
82+
return ErrorCode::SSL_CERTPROBLEM;
4383
case CURLE_SSL_CIPHER:
44-
return ErrorCode::GENERIC_SSL_ERROR;
45-
#if LIBCURL_VERSION_NUM >= 0x073e00
84+
return ErrorCode::SSL_CIPHER;
4685
case CURLE_PEER_FAILED_VERIFICATION:
47-
return ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR;
48-
#else
49-
case CURLE_SSL_CACERT:
50-
return ErrorCode::SSL_CACERT_ERROR;
51-
#endif
86+
return ErrorCode::PEER_FAILED_VERIFICATION;
87+
case CURLE_BAD_CONTENT_ENCODING:
88+
return ErrorCode::BAD_CONTENT_ENCODING;
89+
case CURLE_FILESIZE_EXCEEDED:
90+
return ErrorCode::FILESIZE_EXCEEDED;
5291
case CURLE_USE_SSL_FAILED:
92+
return ErrorCode::USE_SSL_FAILED;
93+
case CURLE_SEND_FAIL_REWIND:
94+
return ErrorCode::SEND_FAIL_REWIND;
5395
case CURLE_SSL_ENGINE_INITFAILED:
54-
return ErrorCode::GENERIC_SSL_ERROR;
96+
return ErrorCode::SSL_ENGINE_INITFAILED;
97+
case CURLE_LOGIN_DENIED:
98+
return ErrorCode::LOGIN_DENIED;
5599
case CURLE_SSL_CACERT_BADFILE:
56-
return ErrorCode::SSL_CACERT_ERROR;
100+
return ErrorCode::SSL_CACERT_BADFILE;
57101
case CURLE_SSL_SHUTDOWN_FAILED:
58-
return ErrorCode::GENERIC_SSL_ERROR;
102+
return ErrorCode::SSL_SHUTDOWN_FAILED;
103+
case CURLE_AGAIN:
104+
return ErrorCode::AGAIN;
59105
case CURLE_SSL_CRL_BADFILE:
106+
return ErrorCode::SSL_CRL_BADFILE;
60107
case CURLE_SSL_ISSUER_ERROR:
61-
return ErrorCode::SSL_CACERT_ERROR;
62-
case CURLE_TOO_MANY_REDIRECTS:
63-
return ErrorCode::TOO_MANY_REDIRECTS;
108+
return ErrorCode::SSL_ISSUER_ERROR;
109+
case CURLE_CHUNK_FAILED:
110+
return ErrorCode::CHUNK_FAILED;
111+
case CURLE_NO_CONNECTION_AVAILABLE:
112+
return ErrorCode::NO_CONNECTION_AVAILABLE;
113+
case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
114+
return ErrorCode::SSL_PINNEDPUBKEYNOTMATCH;
115+
case CURLE_SSL_INVALIDCERTSTATUS:
116+
return ErrorCode::SSL_INVALIDCERTSTATUS;
117+
case CURLE_HTTP2_STREAM:
118+
return ErrorCode::HTTP2_STREAM;
119+
case CURLE_RECURSIVE_API_CALL:
120+
return ErrorCode::RECURSIVE_API_CALL;
121+
case CURLE_AUTH_ERROR:
122+
return ErrorCode::AUTH_ERROR;
123+
case CURLE_HTTP3:
124+
return ErrorCode::HTTP3;
125+
case CURLE_QUIC_CONNECT_ERROR:
126+
return ErrorCode::QUIC_CONNECT_ERROR;
127+
case CURLE_PROXY:
128+
return ErrorCode::PROXY;
129+
case CURLE_SSL_CLIENTCERT:
130+
return ErrorCode::SSL_CLIENTCERT;
131+
case CURLE_UNRECOVERABLE_POLL:
132+
return ErrorCode::UNRECOVERABLE_POLL;
133+
case CURLE_TOO_LARGE:
134+
return ErrorCode::TOO_LARGE;
64135
default:
65-
return ErrorCode::INTERNAL_ERROR;
136+
return ErrorCode::UNKNOWN_ERROR;
66137
}
67138
}
68139

include/cpr/error.h

+74-15
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,91 @@
99

1010
namespace cpr {
1111

12+
/**
13+
* cpr error codes that match the ones found inside 'curl.h'.
14+
* These error codes only include relevant error codes meaning no support for e.g. FTP errors since cpr does only support HTTP.
15+
**/
1216
enum class ErrorCode {
17+
/**
18+
* Everything is good and no error occurred.
19+
**/
1320
OK = 0,
14-
CONNECTION_FAILURE,
15-
EMPTY_RESPONSE,
16-
HOST_RESOLUTION_FAILURE,
17-
INTERNAL_ERROR,
18-
INVALID_URL_FORMAT,
19-
NETWORK_RECEIVE_ERROR,
20-
NETWORK_SEND_FAILURE,
21+
UNSUPPORTED_PROTOCOL,
22+
FAILED_INIT,
23+
URL_MALFORMAT,
24+
NOT_BUILT_IN,
25+
COULDNT_RESOLVE_PROXY,
26+
COULDNT_RESOLVE_HOST,
27+
COULDNT_CONNECT,
28+
WEIRD_SERVER_REPLY,
29+
REMOTE_ACCESS_DENIED,
30+
HTTP2,
31+
PARTIAL_FILE,
32+
QUOTE_ERROR,
33+
HTTP_RETURNED_ERROR,
34+
WRITE_ERROR,
35+
UPLOAD_FAILED,
36+
READ_ERROR,
37+
OUT_OF_MEMORY,
2138
OPERATION_TIMEDOUT,
22-
PROXY_RESOLUTION_FAILURE,
39+
RANGE_ERROR,
40+
HTTP_POST_ERROR,
2341
SSL_CONNECT_ERROR,
24-
SSL_LOCAL_CERTIFICATE_ERROR,
25-
SSL_REMOTE_CERTIFICATE_ERROR,
26-
SSL_CACERT_ERROR,
27-
GENERIC_SSL_ERROR,
28-
UNSUPPORTED_PROTOCOL,
29-
REQUEST_CANCELLED,
42+
BAD_DOWNLOAD_RESUME,
43+
FILE_COULDNT_READ_FILE,
44+
FUNCTION_NOT_FOUND,
45+
ABORTED_BY_CALLBACK,
46+
BAD_FUNCTION_ARGUMENT,
47+
INTERFACE_FAILED,
48+
OBSOLETE46,
3049
TOO_MANY_REDIRECTS,
50+
UNKNOWN_OPTION,
51+
SETOPT_OPTION_SYNTAX,
52+
GOT_NOTHING,
53+
SSL_ENGINE_NOTFOUND,
54+
SSL_ENGINE_SETFAILED,
55+
SEND_ERROR,
56+
RECV_ERROR,
57+
SSL_CERTPROBLEM,
58+
SSL_CIPHER,
59+
PEER_FAILED_VERIFICATION,
60+
BAD_CONTENT_ENCODING,
61+
FILESIZE_EXCEEDED,
62+
USE_SSL_FAILED,
63+
SEND_FAIL_REWIND,
64+
SSL_ENGINE_INITFAILED,
65+
LOGIN_DENIED,
66+
SSL_CACERT_BADFILE,
67+
SSL_SHUTDOWN_FAILED,
68+
AGAIN,
69+
SSL_CRL_BADFILE,
70+
SSL_ISSUER_ERROR,
71+
CHUNK_FAILED,
72+
NO_CONNECTION_AVAILABLE,
73+
SSL_PINNEDPUBKEYNOTMATCH,
74+
SSL_INVALIDCERTSTATUS,
75+
HTTP2_STREAM,
76+
RECURSIVE_API_CALL,
77+
AUTH_ERROR,
78+
HTTP3,
79+
QUIC_CONNECT_ERROR,
80+
PROXY,
81+
SSL_CLIENTCERT,
82+
UNRECOVERABLE_POLL,
83+
TOO_LARGE,
84+
/**
85+
* An unknown error inside curl occurred.
86+
* Please try to reproduce it and then report it to us.
87+
* It might be that there is a new curl error code we are not aware yet.
88+
* Reporting bugs: https://github.com/libcpr/cpr
89+
**/
3190
UNKNOWN_ERROR = 1000,
3291
};
3392

3493
class Error {
3594
public:
3695
ErrorCode code = ErrorCode::OK;
37-
std::string message{};
96+
std::string message;
3897

3998
Error() = default;
4099

test/callback_tests.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ TEST(CallbackPatchTests, CallbackPatchFunctionTextReferenceTest) {
738738
TEST(CallbackDataTests, CallbackReadFunctionCancelTest) {
739739
Url url{server->GetBaseUrl() + "/url_post.html"};
740740
Response response = cpr::Post(url, cpr::ReadCallback([](char* /*buffer*/, size_t& /*size*/, intptr_t /*userdata*/) -> size_t { return false; }));
741-
EXPECT_EQ(response.error.code, ErrorCode::REQUEST_CANCELLED);
741+
EXPECT_TRUE((response.error.code == ErrorCode::ABORTED_BY_CALLBACK) || (response.error.code == ErrorCode::WRITE_ERROR));
742742
}
743743

744744
TEST(CallbackDataTests, CallbackReadFunctionTextTest) {
@@ -858,7 +858,7 @@ TEST(CallbackDataTests, CallbackReadFunctionChunkedTest) {
858858
TEST(CallbackDataTests, CallbackHeaderFunctionCancelTest) {
859859
Url url{server->GetBaseUrl() + "/url_post.html"};
860860
Response response = Post(url, HeaderCallback{[](const std::string_view& /*header*/, intptr_t /*userdata*/) -> bool { return false; }});
861-
EXPECT_EQ(response.error.code, ErrorCode::REQUEST_CANCELLED);
861+
EXPECT_TRUE((response.error.code == ErrorCode::ABORTED_BY_CALLBACK) || (response.error.code == ErrorCode::WRITE_ERROR));
862862
}
863863

864864
TEST(CallbackDataTests, CallbackHeaderFunctionTextTest) {
@@ -878,7 +878,7 @@ TEST(CallbackDataTests, CallbackHeaderFunctionTextTest) {
878878
TEST(CallbackDataTests, CallbackWriteFunctionCancelTest) {
879879
Url url{server->GetBaseUrl() + "/url_post.html"};
880880
Response response = Post(url, WriteCallback{[](const std::string_view& /*header*/, intptr_t /*userdata*/) -> bool { return false; }});
881-
EXPECT_EQ(response.error.code, ErrorCode::REQUEST_CANCELLED);
881+
EXPECT_TRUE((response.error.code == ErrorCode::ABORTED_BY_CALLBACK) || (response.error.code == ErrorCode::WRITE_ERROR));
882882
}
883883

884884
TEST(CallbackDataTests, CallbackWriteFunctionTextTest) {
@@ -898,7 +898,7 @@ TEST(CallbackDataTests, CallbackWriteFunctionTextTest) {
898898
TEST(CallbackDataTests, CallbackProgressFunctionCancelTest) {
899899
Url url{server->GetBaseUrl() + "/url_post.html"};
900900
Response response = Post(url, ProgressCallback{[](size_t /*downloadTotal*/, size_t /*downloadNow*/, size_t /*uploadTotal*/, size_t /*uploadNow*/, intptr_t /*userdata*/) -> bool { return false; }});
901-
EXPECT_EQ(response.error.code, ErrorCode::REQUEST_CANCELLED);
901+
EXPECT_TRUE((response.error.code == ErrorCode::ABORTED_BY_CALLBACK) || (response.error.code == ErrorCode::WRITE_ERROR));
902902
}
903903

904904
TEST(CallbackDataTests, CallbackProgressFunctionTotalTest) {

test/error_tests.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ TEST(ErrorTests, InvalidURLFailure) {
2424
Url url{"???"};
2525
Response response = cpr::Get(url);
2626
EXPECT_EQ(0, response.status_code);
27-
EXPECT_EQ(ErrorCode::INVALID_URL_FORMAT, response.error.code);
27+
EXPECT_EQ(ErrorCode::URL_MALFORMAT, response.error.code);
2828
}
2929

3030
TEST(ErrorTests, TimeoutFailure) {
@@ -45,16 +45,16 @@ TEST(ErrorTests, ConnectTimeoutFailure) {
4545
Url url{"http://localhost:67"};
4646
Response response = cpr::Get(url, cpr::ConnectTimeout{1});
4747
EXPECT_EQ(0, response.status_code);
48-
// Sometimes a CONNECTION_FAILURE happens before the OPERATION_TIMEDOUT:
49-
EXPECT_TRUE(response.error.code == ErrorCode::OPERATION_TIMEDOUT || response.error.code == ErrorCode::CONNECTION_FAILURE);
48+
// Sometimes a COULDNT_CONNECT happens before the OPERATION_TIMEDOUT:
49+
EXPECT_TRUE(response.error.code == ErrorCode::OPERATION_TIMEDOUT || response.error.code == ErrorCode::COULDNT_CONNECT);
5050
}
5151

5252
TEST(ErrorTests, ChronoConnectTimeoutFailure) {
5353
Url url{"http://localhost:67"};
5454
Response response = cpr::Get(url, cpr::ConnectTimeout{std::chrono::milliseconds{1}});
5555
EXPECT_EQ(0, response.status_code);
56-
// Sometimes a CONNECTION_FAILURE happens before the OPERATION_TIMEDOUT:
57-
EXPECT_TRUE(response.error.code == ErrorCode::OPERATION_TIMEDOUT || response.error.code == ErrorCode::CONNECTION_FAILURE);
56+
// Sometimes a COULDNT_CONNECT happens before the OPERATION_TIMEDOUT:
57+
EXPECT_TRUE(response.error.code == ErrorCode::OPERATION_TIMEDOUT || response.error.code == ErrorCode::COULDNT_CONNECT);
5858
}
5959

6060
TEST(ErrorTests, LowSpeedTimeFailure) {
@@ -76,7 +76,7 @@ TEST(ErrorTests, ProxyFailure) {
7676
Response response = cpr::Get(url, cpr::Proxies{{"http", "http://bad_host.libcpr.org"}});
7777
EXPECT_EQ(url, response.url);
7878
EXPECT_EQ(0, response.status_code);
79-
EXPECT_EQ(ErrorCode::PROXY_RESOLUTION_FAILURE, response.error.code);
79+
EXPECT_EQ(ErrorCode::COULDNT_RESOLVE_PROXY, response.error.code);
8080
}
8181

8282
TEST(ErrorTests, BoolFalseTest) {

test/get_tests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ TEST(BasicTests, BadHostTest) {
112112
EXPECT_EQ(std::string{}, response.text);
113113
EXPECT_EQ(url, response.url);
114114
EXPECT_EQ(0, response.status_code);
115-
EXPECT_EQ(ErrorCode::HOST_RESOLUTION_FAILURE, response.error.code);
115+
EXPECT_EQ(ErrorCode::COULDNT_RESOLVE_HOST, response.error.code);
116116
}
117117

118118
TEST(CookiesTests, BasicCookiesTest) {

test/head_tests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ TEST(HeadTests, BadHostHeadTest) {
4747
EXPECT_EQ(std::string{}, response.text);
4848
EXPECT_EQ(url, response.url);
4949
EXPECT_EQ(0, response.status_code);
50-
EXPECT_EQ(ErrorCode::HOST_RESOLUTION_FAILURE, response.error.code);
50+
EXPECT_EQ(ErrorCode::COULDNT_RESOLVE_HOST, response.error.code);
5151
}
5252

5353
TEST(HeadTests, CookieHeadTest) {

test/post_tests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ TEST(UrlEncodedPostTests, UrlPostBadHostTest) {
119119
EXPECT_EQ(url, response.url);
120120
EXPECT_EQ(std::string{}, response.header["content-type"]);
121121
EXPECT_EQ(0, response.status_code);
122-
EXPECT_EQ(ErrorCode::HOST_RESOLUTION_FAILURE, response.error.code);
122+
EXPECT_EQ(ErrorCode::COULDNT_RESOLVE_HOST, response.error.code);
123123
}
124124

125125
TEST(UrlEncodedPostTests, FormPostSingleTest) {

test/raw_body_tests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ TEST(BodyPostTests, UrlPostBadHostTest) {
110110
EXPECT_EQ(url, response.url);
111111
EXPECT_EQ(std::string{}, response.header["content-type"]);
112112
EXPECT_EQ(0, response.status_code);
113-
EXPECT_EQ(ErrorCode::HOST_RESOLUTION_FAILURE, response.error.code);
113+
EXPECT_EQ(ErrorCode::COULDNT_RESOLVE_HOST, response.error.code);
114114
}
115115

116116
TEST(BodyPostTests, StringMoveBodyTest) {

0 commit comments

Comments
 (0)