Currently, we use `assert` in RPC code to document logic and code assumptions. However, it seems a bit extreme to abort all of Bitcoin Core on an assert failure in one of the RPC threads. I suggest to replace all checks with a macro `THROW_LOGIC_ERROR_IF_ASSERT_FAILS(condition)` that does what it says. That logic error will then be returned to the rpc caller and will include instructions to report the error to our issue tracker.

Any objections or naming suggestions for that macro?
"           \"statistics\": {      (object) numeric statistics about BIP9 signalling for a softfork\n"
            "              \"period\": xx,     (numeric) the length in blocks of the BIP9 signalling period \n"
            "              \"threshold\": xx,  (numeric) the number of blocks with the version bit set required to activate the feature \n"
            "              \"elapsed\": xx,    (numeric) the number of blocks elapsed since the beginning of the current period \n"
            "              \"count\": xx,      (numeric) the number of blocks with the version bit set in the current period \n"
            "              \"possible\": xx    (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n"
            "           }\n"
            "        },\n"
            "        \"height\": \"xxxxxx\",     (numeric) height of the first block which the rules are or will be enforced (only for \"buried\" type, or \"bip9\" type with \"active\" status)\n"
            "        \"active\": xx,           (boolean) true if the rules are enforced for the mempool and the next block\n"
            "     }\n"
            "  }\n"
            "  \"warnings\" : \"...\",           (string) any network and blockchain warnings.\n"
            "}\n"
                },
                RPCExamples{
                    HelpExampleCli("getblockchaininfo", "")
            + HelpExampleRpc("getblockchaininfo", "")
                },
            }.Check(request);
    LOCK(cs_main);
    const CBlockIndex* tip = ::ChainActive().Tip();
    UniValue obj(UniValue::VOBJ);
    obj.pushKV("chain",                 Params().NetworkIDString());
    obj.pushKV("blocks",                (int)::ChainActive().Height());
    obj.pushKV("headers",               pindexBestHeader ? pindexBestHeader->nHeight : -1);
    obj.pushKV("bestblockhash",         tip->GetBlockHash().GetHex());
    obj.pushKV("difficulty",            (double)GetDifficulty(tip));
    obj.pushKV("mediantime",            (int64_t)tip->GetMedianTimePast());
    obj.pushKV("verificationprogress",  GuessVerificationProgress(Params().TxData(), tip));