Skip to content

Commit b1c3c10

Browse files
committed
feat: command - handle argument errors via onUsageError()
1 parent 20c63f2 commit b1c3c10

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

console/cli_helper.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,31 @@ func onUsageError(_ context.Context, _ *cli.Command, err error, _ bool) error {
292292
return nil
293293
}
294294
}
295+
if errMsg := err.Error(); strings.HasPrefix(errMsg, "invalid value") && strings.Contains(errMsg, "for argument") {
296+
var value, argument string
297+
if _, parseErr := fmt.Sscanf(errMsg, "invalid value %q for argument %s", &value, &argument); parseErr == nil {
298+
var subErrMsg string
299+
subErrMsgPos := strings.Index(errMsg, ":")
300+
if subErrMsgPos != -1 {
301+
subErrMsg = errMsg[subErrMsgPos+2:]
302+
}
303+
color.Red().Printfln("Invalid value '%s' for argument '%s'. Error: %s", value, strings.TrimSuffix(argument, ":"), subErrMsg)
304+
return nil
305+
}
306+
}
307+
308+
if errMsg := err.Error(); strings.HasPrefix(errMsg, "sufficient count of arg") && strings.Contains(errMsg, "not provided") {
309+
var argument string
310+
var given, expected int
311+
if _, parseErr := fmt.Sscanf(errMsg, "sufficient count of arg %s not provided, given %d expected %d", &argument, &given, &expected); parseErr == nil {
312+
if expected == 1 {
313+
color.Red().Printfln("The '%s' argument requires a value.", argument)
314+
} else {
315+
color.Red().Printfln("The '%s' argument requires at least %d values.", argument, expected)
316+
}
317+
return nil
318+
}
319+
}
295320

296321
return err
297322
}

console/cli_helper_test.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestShowCommandHelp_HelpPrinterCustom(t *testing.T) {
5959
Test command
6060
6161
Usage:
62-
test [global options] test:foo [options] <string_arg> [uint16_arg] [string_args...]
62+
test [global options] test:foo [options] <string_arg> <two_string_args...> [uint16_arg] [any_count_string_args...]
6363
6464
Global options:
6565
-h, --help Show help
@@ -124,6 +124,27 @@ Options:
124124
color.Red().Sprint("Invalid value 'not-a-number' for option 'int'."),
125125
},
126126
},
127+
{
128+
name: "argument need a value",
129+
call: "test:foo --int 0",
130+
containsOutput: []string{
131+
color.Red().Sprint("The 'string_arg' argument requires a value."),
132+
},
133+
},
134+
{
135+
name: "argument need a few values",
136+
call: "test:foo --int 0 string_arg",
137+
containsOutput: []string{
138+
color.Red().Sprint("The 'two_string_args' argument requires at least 2 values."),
139+
},
140+
},
141+
{
142+
name: "argument value is not valid",
143+
call: "test:foo --int 0 string_arg string_args1 string_args2 not-a-number",
144+
containsOutput: []string{
145+
color.Red().Sprint("Invalid value 'not-a-number' for argument 'uint16_arg'. Error: strconv.ParseUint: parsing \"not-a-number\": invalid syntax"),
146+
},
147+
},
127148
{
128149
name: "no ansi color",
129150
call: "--no-ansi",
@@ -192,12 +213,18 @@ func (receiver *TestFooCommand) Extend() command.Extend {
192213
Usage: "string argument",
193214
Required: true,
194215
},
216+
&command.ArgumentStringSlice{
217+
Name: "two_string_args",
218+
Usage: "string arguments",
219+
Min: 2,
220+
Max: 2,
221+
},
195222
&command.ArgumentUint16{
196223
Name: "uint16_arg",
197224
Usage: "uint16 argument",
198225
},
199226
&command.ArgumentStringSlice{
200-
Name: "string_args",
227+
Name: "any_count_string_args",
201228
Usage: "string arguments",
202229
Min: 0,
203230
Max: -1,

0 commit comments

Comments
 (0)