diff --git a/plugins/libplugin.c b/plugins/libplugin.c index 74311b81c..ee45e8874 100644 --- a/plugins/libplugin.c +++ b/plugins/libplugin.c @@ -165,7 +165,8 @@ jsonrpc_request_start_(struct plugin *plugin, struct command *cmd, json_add_string(out->js, "jsonrpc", "2.0"); json_add_u64(out->js, "id", out->id); json_add_string(out->js, "method", method); - json_object_start(out->js, "params"); + if (out->errcb) + json_object_start(out->js, "params"); return out; } @@ -551,16 +552,26 @@ static void handle_rpc_reply(struct plugin *plugin, const jsmntok_t *toks) uintmap_del(&plugin->out_reqs, out->id); contenttok = json_get_member(plugin->rpc_buffer, toks, "error"); - if (contenttok) - res = out->errcb(out->cmd, plugin->rpc_buffer, - contenttok, out->arg); - else { + if (contenttok) { + if (out->errcb) + res = out->errcb(out->cmd, plugin->rpc_buffer, + contenttok, out->arg); + else + res = out->cb(out->cmd, plugin->rpc_buffer, + toks, out->arg); + } else { contenttok = json_get_member(plugin->rpc_buffer, toks, "result"); if (!contenttok) plugin_err(plugin, "Bad JSONRPC, no 'error' nor 'result': '%.*s'", json_tok_full_len(toks), json_tok_full(plugin->rpc_buffer, toks)); - res = out->cb(out->cmd, plugin->rpc_buffer, contenttok, out->arg); + /* errcb is NULL if it's a single whole-object callback */ + if (out->errcb) + res = out->cb(out->cmd, plugin->rpc_buffer, contenttok, + out->arg); + else + res = out->cb(out->cmd, plugin->rpc_buffer, toks, + out->arg); } assert(res == &pending || res == &complete); @@ -570,7 +581,8 @@ struct command_result * send_outreq(struct plugin *plugin, const struct out_req *req) { /* The "param" object. */ - json_object_end(req->js); + if (req->errcb) + json_object_end(req->js); json_object_end(req->js); json_stream_close(req->js, req->cmd); diff --git a/plugins/libplugin.h b/plugins/libplugin.h index feb6b4d81..6b90ef6e5 100644 --- a/plugins/libplugin.h +++ b/plugins/libplugin.h @@ -117,6 +117,8 @@ struct out_req *jsonrpc_request_start_(struct plugin *plugin, void *arg), void *arg); +/* This variant has callbacks received whole obj, not "result" or + * "error" members. */ #define jsonrpc_request_start(plugin, cmd, method, cb, errcb, arg) \ jsonrpc_request_start_((plugin), (cmd), (method), \ typesafe_cb_preargs(struct command_result *, void *, \ @@ -132,6 +134,18 @@ struct out_req *jsonrpc_request_start_(struct plugin *plugin, (arg)) +/* This variant has callbacks received whole obj, not "result" or + * "error" members. It also doesn't start params{}. */ +#define jsonrpc_request_whole_object_start(plugin, cmd, method, cb, arg) \ + jsonrpc_request_start_((plugin), (cmd), (method), \ + typesafe_cb_preargs(struct command_result *, void *, \ + (cb), (arg), \ + struct command *command, \ + const char *buf, \ + const jsmntok_t *result), \ + NULL, \ + (arg)) + /* Helper to create a JSONRPC2 response stream with a "result" object. */ struct json_stream *jsonrpc_stream_success(struct command *cmd);