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?
{
public:
    RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples);
    std::string ToString() const;
    
    bool IsValidNumArgs(size_t num_args) const;
    /**
     * 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.
     */
    inline void Check(const JSONRPCRequest& request) const {
        if (request.fHelp || !IsValidNumArgs(request.params.size())) {
            throw std::runtime_error(ToString());
        }
    }
private:
    const std::string m_name;
    const std::string m_description;
    const std::vector<RPCArg> m_args;
    const RPCResults m_results;
    const RPCExamples m_examples;
};
#endif