Skip to content

Commit bb843ad

Browse files
committed
Merge #8722: bitcoin-cli: More detailed error reporting
381826d bitcoin-cli: More detailed error reporting (Wladimir J. van der Laan)
2 parents ab0b411 + 381826d commit bb843ad

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

src/bitcoin-cli.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,42 @@ static bool AppInitRPC(int argc, char* argv[])
116116
/** Reply structure for request_done to fill in */
117117
struct HTTPReply
118118
{
119+
HTTPReply(): status(0), error(-1) {}
120+
119121
int status;
122+
int error;
120123
std::string body;
121124
};
122125

126+
const char *http_errorstring(int code)
127+
{
128+
switch(code) {
129+
#if LIBEVENT_VERSION_NUMBER >= 0x02010300
130+
case EVREQ_HTTP_TIMEOUT:
131+
return "timeout reached";
132+
case EVREQ_HTTP_EOF:
133+
return "EOF reached";
134+
case EVREQ_HTTP_INVALID_HEADER:
135+
return "error while reading header, or invalid header";
136+
case EVREQ_HTTP_BUFFER_ERROR:
137+
return "error encountered while reading or writing";
138+
case EVREQ_HTTP_REQUEST_CANCEL:
139+
return "request was canceled";
140+
case EVREQ_HTTP_DATA_TOO_LONG:
141+
return "response body is larger than allowed";
142+
#endif
143+
default:
144+
return "unknown";
145+
}
146+
}
147+
123148
static void http_request_done(struct evhttp_request *req, void *ctx)
124149
{
125150
HTTPReply *reply = static_cast<HTTPReply*>(ctx);
126151

127152
if (req == NULL) {
128-
/* If req is NULL, it means an error occurred while connecting, but
129-
* I'm not sure how to find out which one. We also don't really care.
153+
/* If req is NULL, it means an error occurred while connecting: the
154+
* error code will have been passed to http_error_cb.
130155
*/
131156
reply->status = 0;
132157
return;
@@ -145,6 +170,14 @@ static void http_request_done(struct evhttp_request *req, void *ctx)
145170
}
146171
}
147172

173+
#if LIBEVENT_VERSION_NUMBER >= 0x02010300
174+
static void http_error_cb(enum evhttp_request_error err, void *ctx)
175+
{
176+
HTTPReply *reply = static_cast<HTTPReply*>(ctx);
177+
reply->error = err;
178+
}
179+
#endif
180+
148181
UniValue CallRPC(const string& strMethod, const UniValue& params)
149182
{
150183
std::string host = GetArg("-rpcconnect", DEFAULT_RPCCONNECT);
@@ -165,6 +198,9 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
165198
struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII
166199
if (req == NULL)
167200
throw runtime_error("create http request failed");
201+
#if LIBEVENT_VERSION_NUMBER >= 0x02010300
202+
evhttp_request_set_error_cb(req, http_error_cb);
203+
#endif
168204

169205
// Get credentials
170206
std::string strRPCUserColonPass;
@@ -204,7 +240,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
204240
event_base_free(base);
205241

206242
if (response.status == 0)
207-
throw CConnectionFailed("couldn't connect to server");
243+
throw CConnectionFailed(strprintf("couldn't connect to server (%d %s)", response.error, http_errorstring(response.error)));
208244
else if (response.status == HTTP_UNAUTHORIZED)
209245
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
210246
else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)

0 commit comments

Comments
 (0)