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
Assignees
Labels
bug Something isn't working

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;
}

@grafikrobot grafikrobot self-assigned this Mar 7, 2025
@grafikrobot grafikrobot added the bug Something isn't working label Mar 7, 2025
@grafikrobot grafikrobot moved this to 🏗 In progress in BFG Tasks Mar 7, 2025
@grafikrobot grafikrobot moved this from 🏗 In progress to 🔖 Ready in BFG Tasks Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: 🔖 Ready
Development

No branches or pull requests

2 participants