Merge #8722: bitcoin-cli: More detailed error reporting
381826d bitcoin-cli: More detailed error reporting (Wladimir J. van der Laan)
This commit is contained in:
parent
d87c156f19
commit
8e610c0ac3
@ -131,17 +131,42 @@ static int AppInitRPC(int argc, char* argv[])
|
|||||||
/** Reply structure for request_done to fill in */
|
/** Reply structure for request_done to fill in */
|
||||||
struct HTTPReply
|
struct HTTPReply
|
||||||
{
|
{
|
||||||
|
HTTPReply(): status(0), error(-1) {}
|
||||||
|
|
||||||
int status;
|
int status;
|
||||||
|
int error;
|
||||||
std::string body;
|
std::string body;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *http_errorstring(int code)
|
||||||
|
{
|
||||||
|
switch(code) {
|
||||||
|
#if LIBEVENT_VERSION_NUMBER >= 0x02010300
|
||||||
|
case EVREQ_HTTP_TIMEOUT:
|
||||||
|
return "timeout reached";
|
||||||
|
case EVREQ_HTTP_EOF:
|
||||||
|
return "EOF reached";
|
||||||
|
case EVREQ_HTTP_INVALID_HEADER:
|
||||||
|
return "error while reading header, or invalid header";
|
||||||
|
case EVREQ_HTTP_BUFFER_ERROR:
|
||||||
|
return "error encountered while reading or writing";
|
||||||
|
case EVREQ_HTTP_REQUEST_CANCEL:
|
||||||
|
return "request was canceled";
|
||||||
|
case EVREQ_HTTP_DATA_TOO_LONG:
|
||||||
|
return "response body is larger than allowed";
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void http_request_done(struct evhttp_request *req, void *ctx)
|
static void http_request_done(struct evhttp_request *req, void *ctx)
|
||||||
{
|
{
|
||||||
HTTPReply *reply = static_cast<HTTPReply*>(ctx);
|
HTTPReply *reply = static_cast<HTTPReply*>(ctx);
|
||||||
|
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
/* If req is NULL, it means an error occurred while connecting, but
|
/* If req is NULL, it means an error occurred while connecting: the
|
||||||
* I'm not sure how to find out which one. We also don't really care.
|
* error code will have been passed to http_error_cb.
|
||||||
*/
|
*/
|
||||||
reply->status = 0;
|
reply->status = 0;
|
||||||
return;
|
return;
|
||||||
@ -160,6 +185,14 @@ static void http_request_done(struct evhttp_request *req, void *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LIBEVENT_VERSION_NUMBER >= 0x02010300
|
||||||
|
static void http_error_cb(enum evhttp_request_error err, void *ctx)
|
||||||
|
{
|
||||||
|
HTTPReply *reply = static_cast<HTTPReply*>(ctx);
|
||||||
|
reply->error = err;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UniValue CallRPC(const string& strMethod, const UniValue& params)
|
UniValue CallRPC(const string& strMethod, const UniValue& params)
|
||||||
{
|
{
|
||||||
std::string host = GetArg("-rpcconnect", DEFAULT_RPCCONNECT);
|
std::string host = GetArg("-rpcconnect", DEFAULT_RPCCONNECT);
|
||||||
@ -180,6 +213,9 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
|
|||||||
struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII
|
struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII
|
||||||
if (req == NULL)
|
if (req == NULL)
|
||||||
throw runtime_error("create http request failed");
|
throw runtime_error("create http request failed");
|
||||||
|
#if LIBEVENT_VERSION_NUMBER >= 0x02010300
|
||||||
|
evhttp_request_set_error_cb(req, http_error_cb);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Get credentials
|
// Get credentials
|
||||||
std::string strRPCUserColonPass;
|
std::string strRPCUserColonPass;
|
||||||
@ -219,7 +255,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
|
|||||||
event_base_free(base);
|
event_base_free(base);
|
||||||
|
|
||||||
if (response.status == 0)
|
if (response.status == 0)
|
||||||
throw CConnectionFailed("couldn't connect to server");
|
throw CConnectionFailed(strprintf("couldn't connect to server (%d %s)", response.error, http_errorstring(response.error)));
|
||||||
else if (response.status == HTTP_UNAUTHORIZED)
|
else if (response.status == HTTP_UNAUTHORIZED)
|
||||||
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
|
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
|
||||||
else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)
|
else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)
|
||||||
|
Loading…
Reference in New Issue
Block a user