Skip to content

Commit dfa50a8

Browse files
committed
Make suggestions in error message
A very simple scheme to help the user. Test: cvd version # match found, no effect Test: cvd q # no match, no options to suggest Test: cvd crate # no match, suggests options
1 parent 8d331a8 commit dfa50a8

File tree

1 file changed

+41
-4
lines changed

1 file changed

+41
-4
lines changed

base/cvd/cuttlefish/host/commands/cvd/cli/request_context.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
#include "host/commands/cvd/cli/request_context.h"
1818

1919
#include <memory>
20+
#include <string>
2021
#include <vector>
2122

2223
#include <android-base/logging.h>
24+
#include <android-base/strings.h>
2325

2426
#include "common/libs/utils/result.h"
2527
#include "host/commands/cvd/cli/command_request.h"
@@ -57,6 +59,30 @@
5759

5860
namespace cuttlefish {
5961

62+
namespace {
63+
64+
std::vector<std::string> GetPossibleCommands(
65+
const CommandRequest& request,
66+
const std::vector<std::unique_ptr<CvdCommandHandler>>& handlers) {
67+
std::vector<std::string> possibilities;
68+
if (request.Subcommand().empty()) {
69+
return possibilities;
70+
}
71+
72+
for (auto& handler : handlers) {
73+
for (const std::string& command : handler->CmdList()) {
74+
if (!command.empty() &&
75+
android::base::StartsWith(command, request.Subcommand().front())) {
76+
possibilities.push_back(command);
77+
break;
78+
}
79+
}
80+
}
81+
return possibilities;
82+
}
83+
84+
} // namespace
85+
6086
RequestContext::RequestContext(InstanceManager& instance_manager)
6187
: instance_manager_(instance_manager),
6288
command_sequence_executor_(this->request_handlers_) {
@@ -113,14 +139,25 @@ Result<CvdCommandHandler*> RequestHandler(
113139
compatible_handlers.push_back(handler.get());
114140
}
115141
}
142+
116143
CF_EXPECT(compatible_handlers.size() < 2,
117144
"The command matched multiple handlers which should not happen. "
118145
"Please open a bug with the cvd/Cuttlefish team and include the "
119146
"exact command that raised the error so it can be fixed.");
120-
CF_EXPECTF(compatible_handlers.size() == 1,
121-
"Unable to find a matching command for \"cvd {}\". Maybe there "
122-
"is a typo?\nRun `cvd help` for a list of commands.",
123-
request.Subcommand());
147+
148+
if (compatible_handlers.size() != 1) {
149+
const std::vector<std::string> possible_commands =
150+
GetPossibleCommands(request, handlers);
151+
std::string addendum;
152+
if (!possible_commands.empty()) {
153+
addendum = fmt::format("\n\nDid you mean one of:\n\t{}",
154+
fmt::join(possible_commands, "\n\t"));
155+
}
156+
return CF_ERRF(
157+
"Unable to find a matching command for \"cvd {}\".\nMaybe there "
158+
"is a typo? Run `cvd help` for a list of commands.{}",
159+
request.Subcommand(), addendum);
160+
}
124161
return compatible_handlers[0];
125162
}
126163

0 commit comments

Comments
 (0)