Repository: bitcoin/bitcoin
File: src/rpc/util.cpp (C++)

Code before:
        } else {
            result += "\nResult (" + r.m_cond + "):\n";
        }
        Sections sections;
        r.ToSections(sections);
        result += sections.ToString();
    }
    return result;
}

std::string RPCExamples::ToDescriptionString() const
{
    return m_examples.empty() ? m_examples : "\nExamples:\n" + m_examples;
}

UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request) const
{
    if (request.mode == JSONRPCRequest::GET_ARGS) {
        return GetArgMap();
    }
    /*
     * Check if the given request is valid according to this command or if
     * the user is asking for help information, and throw help when appropriate.
     */
    if (request.mode == JSONRPCRequest::GET_HELP || !IsValidNumArgs(request.params.size())) {
        throw std::runtime_error(ToString());
    }
    UniValue arg_mismatch{UniValue::VOBJ};
    for (size_t i{0}; i < m_args.size(); ++i) {
        const auto& arg{m_args.at(i)};
        UniValue match{arg.MatchesType(request.params[i])};
        if (!match.isTrue()) {
            arg_mismatch.pushKV(strprintf("Position %s (%s)", i + 1, arg.m_names), std::move(match));
        }
    }
    if (!arg_mismatch.empty()) {
        throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Wrong type passed:\n%s", arg_mismatch.write(4)));
    }
    CHECK_NONFATAL(m_req == nullptr);
    m_req = &request;
    UniValue ret = m_fun(*this, request);
    m_req = nullptr;
    if (gArgs.GetBoolArg("-rpcdoccheck", DEFAULT_RPC_DOC_CHECK)) {
        UniValue mismatch{UniValue::VARR};
        for (const auto& res : m_results.m_results) {
            UniValue match{res.MatchesType(ret)};
            if (match.isTrue()) {
                mismatch.setNull();
                break;
            }
            mismatch.push_back(std::move(match));

Review comment (suggestion):
Ah! Took me some time to understand how this fix worked. In case of erroneous help text, a `NonFatalCheckError` exception is thrown from here that was earlier caught by the catch-all handler in `server.cpp`. Now only `HelpException` is caught and the rest, including `NonFatalCheckError`, is bubbled up all the way to the RPC response. https://github.com/bitcoin/bitcoin/blob/e872a566f251c73908de8b6d243c94a6679c2eac/src/rpc/util.cpp#L795-L796

Code after:
        } else {
            result += "\nResult (" + r.m_cond + "):\n";
        }
        Sections sections;
        r.ToSections(sections);
        result += sections.ToString();
    }
    return result;
}

std::string RPCExamples::ToDescriptionString() const
{
    return m_examples.empty() ? m_examples : "\nExamples:\n" + m_examples;
}

UniValue RPCHelpMan::HandleRequest(const JSONRPCRequest& request) const
{
    if (request.mode == JSONRPCRequest::GET_ARGS) {
        return GetArgMap();
    }
    /*
     * Check if the given request is valid according to this command or if
     * the user is asking for help information, and throw help when appropriate.
     */
    if (request.mode == JSONRPCRequest::GET_HELP || !IsValidNumArgs(request.params.size())) {
        throw HelpResult{ToString()};
    }
    UniValue arg_mismatch{UniValue::VOBJ};
    for (size_t i{0}; i < m_args.size(); ++i) {
        const auto& arg{m_args.at(i)};
        UniValue match{arg.MatchesType(request.params[i])};
        if (!match.isTrue()) {
            arg_mismatch.pushKV(strprintf("Position %s (%s)", i + 1, arg.m_names), std::move(match));
        }
    }
    if (!arg_mismatch.empty()) {
        throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Wrong type passed:\n%s", arg_mismatch.write(4)));
    }
    CHECK_NONFATAL(m_req == nullptr);
    m_req = &request;
    UniValue ret = m_fun(*this, request);
    m_req = nullptr;
    if (gArgs.GetBoolArg("-rpcdoccheck", DEFAULT_RPC_DOC_CHECK)) {
        UniValue mismatch{UniValue::VARR};
        for (const auto& res : m_results.m_results) {
            UniValue match{res.MatchesType(ret)};
            if (match.isTrue()) {
                mismatch.setNull();
                break;
            }
            mismatch.push_back(std::move(match));