Check for JSON-RPC errors, and add better logging for it

This commit is contained in:
Lee Clagett
2021-03-03 23:27:22 -05:00
parent 01b269e3ca
commit 1766276aad
5 changed files with 47 additions and 18 deletions

View File

@@ -37,6 +37,7 @@
#include "misc_log_ex.h" // monero/contrib/epee/include
#include "net/http_client.h" // monero/contrib/epee/include
#include "net/zmq.h" // monero/src
#include "serialization/json_object.h" // monero/src
namespace lws
{
@@ -160,6 +161,32 @@ namespace rpc
};
} // detail
expect<void> client::get_response(cryptonote::rpc::Message& response, const std::chrono::seconds timeout, const source_location loc)
{
expect<std::string> message = get_message(timeout);
if (!message)
return message.error();
try
{
cryptonote::rpc::FullMessage fm{std::move(*message)};
const cryptonote::rpc::error json_error = fm.getError();
if (!json_error.use)
{
response.fromJson(fm.getMessage());
return success();
}
MERROR("Server returned RPC error: " << json_error.message << " with code " << json_error.code << " called from " << loc);
}
catch (const cryptonote::json::JSON_ERROR& error)
{
MERROR("Failed to parse json response: " << error.what() << " called from " << loc);
}
return {lws::error::bad_daemon_response};
}
expect<std::string> client::get_message(std::chrono::seconds timeout)
{
MONERO_PRECOND(ctx != nullptr);

View File

@@ -38,6 +38,7 @@
#include "rpc/message.h" // monero/src
#include "rpc/daemon_pub.h"
#include "rpc/rates.h"
#include "util/source_location.h"
namespace lws
{
@@ -70,6 +71,9 @@ namespace rpc
: ctx(std::move(ctx)), daemon(), daemon_sub(), signal_sub()
{}
//! Expect `response` as the next message payload unless error.
expect<void> get_response(cryptonote::rpc::Message& response, std::chrono::seconds timeout, source_location loc);
public:
//! A client with no connection (all send/receive functions fail).
explicit client() noexcept
@@ -125,18 +129,13 @@ namespace rpc
//! \return Next available RPC message response from server
expect<std::string> get_message(std::chrono::seconds timeout);
//! \return RPC response `M`, waiting a max of `timeout` seconds.
//! \return RPC response `M`, waiting a max of `timeout` seconds. Log errors as from `loc`.
template<typename M>
expect<M> receive(std::chrono::seconds timeout)
expect<M> receive(const std::chrono::seconds timeout, const source_location loc = {})
{
expect<std::string> message = get_message(timeout);
if (!message)
return message.error();
cryptonote::rpc::FullMessage fm{std::move(*message)};
M out{};
out.fromJson(fm.getMessage());
return out;
M response{};
MONERO_CHECK(get_response(response, timeout, loc));
return response;
}
/*!