lightning-cli: fix error code on invalid options, document them.

The top of the file indicates the following errors:

    #define NO_ERROR 0
    #define ERROR_FROM_LIGHTNINGD 1
    #define ERROR_TALKING_TO_LIGHTNINGD 2
    #define ERROR_USAGE 3

But we didn't use the right one for opt_parse failure, and didn't use the
correct constants everywhere.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-01-03 14:53:15 +10:30
parent a1e894a445
commit 435f8d84dc
3 changed files with 58 additions and 4 deletions

View File

@ -601,6 +601,18 @@ static void opt_show_level(char buf[OPT_SHOW_LEN], const enum log_level *level)
strncpy(buf, log_level_name(*level), OPT_SHOW_LEN-1);
}
/* The standard opt_log_stderr_exit exits with status 1 */
static void opt_log_stderr_exit_usage(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(ERROR_USAGE);
}
int main(int argc, char *argv[])
{
setup_locale();
@ -656,8 +668,8 @@ int main(int argc, char *argv[])
opt_register_version();
opt_early_parse(argc, argv, opt_log_stderr_exit);
opt_parse(&argc, argv, opt_log_stderr_exit);
opt_early_parse(argc, argv, opt_log_stderr_exit_usage);
opt_parse(&argc, argv, opt_log_stderr_exit_usage);
method = argv[1];
if (!method) {
@ -872,7 +884,7 @@ int main(int argc, char *argv[])
}
tal_free(ctx);
opt_free_table();
return 0;
return NO_ERROR;
}
if (format == RAW)
@ -884,5 +896,5 @@ int main(int argc, char *argv[])
}
tal_free(ctx);
opt_free_table();
return 1;
return ERROR_FROM_LIGHTNINGD;
}

View File

@ -130,6 +130,15 @@ BUGS
This manpage documents how it should work, not how it does work. The
pretty printing of results isn't pretty.
EXIT STATUS
-----------
If the command succeeds, the exit status is 0. Otherwise:
* `1`: lightningd(7) returned an error reply (which is printed).
* `2`: we could not talk to lightningd.
* `3`: usage error, such as bad arguments or malformed JSON in the parameters.
AUTHOR
------

View File

@ -937,6 +937,39 @@ def test_cli(node_factory):
j, _ = json.JSONDecoder().raw_decode(out)
assert j == {'help': [{'command': 'help [command]'}]}
# lightningd errors should exit with status 1.
ret = subprocess.run(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}'
.format(l1.daemon.lightning_dir),
'unknown-command'])
assert ret.returncode == 1
# Can't contact will exit with status code 2.
ret = subprocess.run(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir=xxx',
'help'])
assert ret.returncode == 2
# Malformed parameter (invalid json) will exit with status code 3.
ret = subprocess.run(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}'
.format(l1.daemon.lightning_dir),
'listpeers',
'[xxx]'])
assert ret.returncode == 3
# Bad usage should exit with status 3.
ret = subprocess.run(['cli/lightning-cli',
'--bad-param',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}'
.format(l1.daemon.lightning_dir),
'help'])
assert ret.returncode == 3
# Test missing parameters.
try:
# This will error due to missing parameters.