* ConnectAndCallRPC wraps CallRPC with -rpcwait and an exception handler. * * @param[in] rh Pointer to RequestHandler. * @param[in] strMethod Reference to const string method to forward to CallRPC. * @param[in] rpcwallet Reference to const optional string wallet name to forward to CallRPC. * @returns the RPC response as a UniValue object. * @throws a CConnectionFailed std::runtime_
| 837 | * @throws a CConnectionFailed std::runtime_error if connection failed or RPC server still in warmup. |
| 838 | */ |
| 839 | static UniValue ConnectAndCallRPC(BaseRequestHandler* rh, const std::string& strMethod, const std::vector<std::string>& args, const std::optional<std::string>& rpcwallet = {}) |
| 840 | { |
| 841 | UniValue response(UniValue::VOBJ); |
| 842 | // Execute and handle connection failures with -rpcwait. |
| 843 | const bool fWait = gArgs.GetBoolArg("-rpcwait", false); |
| 844 | const int timeout = gArgs.GetIntArg("-rpcwaittimeout", DEFAULT_WAIT_CLIENT_TIMEOUT); |
| 845 | const auto deadline{GetTime<std::chrono::microseconds>() + 1s * timeout}; |
| 846 | |
| 847 | do { |
| 848 | try { |
| 849 | response = CallRPC(rh, strMethod, args, rpcwallet); |
| 850 | if (fWait) { |
| 851 | const UniValue& error = find_value(response, "error"); |
| 852 | if (!error.isNull() && error["code"].get_int() == RPC_IN_WARMUP) { |
| 853 | throw CConnectionFailed("server in warmup"); |
| 854 | } |
| 855 | } |
| 856 | break; // Connection succeeded, no need to retry. |
| 857 | } catch (const CConnectionFailed& e) { |
| 858 | const auto now{GetTime<std::chrono::microseconds>()}; |
| 859 | if (fWait && (timeout <= 0 || now < deadline)) { |
| 860 | UninterruptibleSleep(1s); |
| 861 | } else { |
| 862 | throw CConnectionFailed(strprintf("timeout on transient error: %s", e.what())); |
| 863 | } |
| 864 | } |
| 865 | } while (fWait); |
| 866 | return response; |
| 867 | } |
| 868 | |
| 869 | /** Parse UniValue result to update the message to print to std::cout. */ |
| 870 | static void ParseResult(const UniValue& result, std::string& strPrint) |
no test coverage detected