Returns NULL if it wasn't an error. */
| 72 | |
| 73 | /* Returns NULL if it wasn't an error. */ |
| 74 | static struct command_result *handle_error(struct command *cmd, |
| 75 | struct sent *sent, |
| 76 | const char *buf, |
| 77 | const jsmntok_t *om) |
| 78 | { |
| 79 | const u8 *data; |
| 80 | size_t dlen; |
| 81 | struct tlv_invoice_error *err; |
| 82 | struct json_out *details; |
| 83 | const jsmntok_t *errtok; |
| 84 | |
| 85 | errtok = json_get_member(buf, om, "invoice_error"); |
| 86 | if (!errtok) |
| 87 | return NULL; |
| 88 | |
| 89 | data = json_tok_bin_from_hex(cmd, buf, errtok); |
| 90 | dlen = tal_bytelen(data); |
| 91 | details = json_out_new(cmd); |
| 92 | |
| 93 | plugin_log(cmd->plugin, LOG_DBG, "errtok = %.*s", |
| 94 | json_tok_full_len(errtok), |
| 95 | json_tok_full(buf, errtok)); |
| 96 | json_out_start(details, NULL, '{'); |
| 97 | err = fromwire_tlv_invoice_error(cmd, &data, &dlen); |
| 98 | if (!err) { |
| 99 | plugin_log(cmd->plugin, LOG_DBG, |
| 100 | "Invalid invoice_error %.*s", |
| 101 | json_tok_full_len(errtok), |
| 102 | json_tok_full(buf, errtok)); |
| 103 | json_out_addstr(details, "invoice_error_hex", |
| 104 | tal_strndup(tmpctx, |
| 105 | buf + errtok->start, |
| 106 | errtok->end - errtok->start)); |
| 107 | } else { |
| 108 | char *failstr; |
| 109 | |
| 110 | /* FIXME: with a bit more generate-wire.py support, |
| 111 | * we could have fieldnames and even types. */ |
| 112 | if (err->erroneous_field) |
| 113 | json_out_add(details, "erroneous_field", false, |
| 114 | "%"PRIu64, *err->erroneous_field); |
| 115 | if (err->suggested_value) |
| 116 | json_out_addstr(details, "suggested_value", |
| 117 | tal_hex(tmpctx, |
| 118 | err->suggested_value)); |
| 119 | /* If they don't include this, it'll be empty */ |
| 120 | failstr = tal_strndup(tmpctx, |
| 121 | err->error, |
| 122 | tal_bytelen(err->error)); |
| 123 | json_out_addstr(details, "error", failstr); |
| 124 | } |
| 125 | json_out_end(details, '}'); |
| 126 | discard_result(command_done_err(sent->cmd, |
| 127 | OFFER_BAD_INVREQ_REPLY, |
| 128 | "Remote node sent failure message", |
| 129 | details)); |
| 130 | return command_hook_success(cmd); |
| 131 | } |
no test coverage detected