Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom option lamba error string is dropped when nested under command parser #79

Open
wadechristie opened this issue Sep 11, 2023 · 1 comment

Comments

@wadechristie
Copy link

wadechristie commented Sep 11, 2023

I encountered this problem when attempting to nest a lamba option under a sub-command. The error context returned from the lambda is dropped when unwinding the stack.

Here is an example to demonstrate the behavior:

#include <iostream>
#include <string>

#include <lyra/lyra.hpp>

static lyra::parser_result always_error_cb(std::string const&)
{
    return lyra::parser_result::error(lyra::parser_result_type::no_match, "Custom error message w/ context.");
}

struct subcommand
{
    subcommand(lyra::cli& cli)
    {
        cli.add_argument(lyra::command("subcommand", [this](lyra::group const& g) {
            exec();
        }).add_argument(lyra::opt([](std::string const& s) { return always_error_cb(s); }, "arg").name("--arg")));
    }

private:
    void exec()
    {
        std::cout << "Subcommand" << std::endl;
    }
};

int main(int argc, char const* argv[])
{
    bool show_help { false };
    auto cli
        = lyra::cli()
              .add_argument(lyra::help(show_help))
              .add_argument(lyra::opt([](std::string const& s) { return always_error_cb(s); }, "arg").name("--arg"));
    subcommand subcmd { cli };

    auto result = cli.parse({ argc, argv });

    if (!result)
    {
        std::cerr << "Error: " << result.message() << std::endl;
        return 1;
    }

    if (show_help)
    {
        std::cout << cli << std::endl;
        return 0;
    }

    return result ? 0 : 1;
}

}

Behavior with a top-level argument.

$ ./a.out --test value
Error: Custom error message w/ context.

Behavior with a sub-command argument. The error message with context for the user is lost.

$ ./a.out subcommand --test value
Error: Expected: [--arg <arg>]

The error propagates back up the stack to this point:

if (!subresult)
{
break;
}

And the error context is dropped a few lines later here:

return parse_result::error(p_result.value(),
"Expected: " + parse_info.parser_p->get_usage_text(style));

@wadechristie
Copy link
Author

wadechristie commented Sep 12, 2023

It seems to me the problem is at line 113 with the decision to break out of the loop just before the error would have been returned:

if (!subresult)
{
break;
}
if (subresult.value().type()
== parser_result_type::short_circuit_all)
{
return subresult;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant