| 633 | } |
| 634 | |
| 635 | UniValue RPCMethod::HandleRequest(const JSONRPCRequest& request) const |
| 636 | { |
| 637 | if (request.mode == JSONRPCRequest::GET_ARGS) { |
| 638 | return GetArgMap(); |
| 639 | } |
| 640 | /* |
| 641 | * Check if the given request is valid according to this command or if |
| 642 | * the user is asking for help information, and throw help when appropriate. |
| 643 | */ |
| 644 | if (request.mode == JSONRPCRequest::GET_HELP || !IsValidNumArgs(request.params.size())) { |
| 645 | throw HelpResult{ToString()}; |
| 646 | } |
| 647 | UniValue arg_mismatch{UniValue::VOBJ}; |
| 648 | for (size_t i{0}; i < m_args.size(); ++i) { |
| 649 | const auto& arg{m_args.at(i)}; |
| 650 | UniValue match{arg.MatchesType(request.params[i])}; |
| 651 | if (!match.isTrue()) { |
| 652 | arg_mismatch.pushKV(strprintf("Position %s (%s)", i + 1, arg.m_names), std::move(match)); |
| 653 | } |
| 654 | } |
| 655 | if (!arg_mismatch.empty()) { |
| 656 | throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Wrong type passed:\n%s", arg_mismatch.write(4))); |
| 657 | } |
| 658 | CHECK_NONFATAL(m_req == nullptr); |
| 659 | m_req = &request; |
| 660 | UniValue ret = m_fun(*this, request); |
| 661 | m_req = nullptr; |
| 662 | if (gArgs.GetBoolArg("-rpcdoccheck", DEFAULT_RPC_DOC_CHECK)) { |
| 663 | UniValue mismatch{UniValue::VARR}; |
| 664 | for (const auto& res : m_results.m_results) { |
| 665 | UniValue match{res.MatchesType(ret)}; |
| 666 | if (match.isTrue()) { |
| 667 | mismatch.setNull(); |
| 668 | break; |
| 669 | } |
| 670 | mismatch.push_back(std::move(match)); |
| 671 | } |
| 672 | if (!mismatch.isNull()) { |
| 673 | std::string explain{ |
| 674 | mismatch.empty() ? "no possible results defined" : |
| 675 | mismatch.size() == 1 ? mismatch[0].write(4) : |
| 676 | mismatch.write(4)}; |
| 677 | throw std::runtime_error{ |
| 678 | STR_INTERNAL_BUG(strprintf("RPC call \"%s\" returned incorrect type:\n%s", m_name, explain)), |
| 679 | }; |
| 680 | } |
| 681 | } |
| 682 | return ret; |
| 683 | } |
| 684 | |
| 685 | using CheckFn = void(const RPCArg&); |
| 686 | static const UniValue* DetailMaybeArg(CheckFn* check, const std::vector<RPCArg>& params, const JSONRPCRequest* req, size_t i) |