Skip to content

Commit a20d0c8

Browse files
committed
cli/command: ctx cancel should not print or produce a non zero exit code
The user might kill the CLI through a SIGINT/SIGTERM which cancels the main context we pass around. Currently the context cancel error is printed alongside any other wrapped error with a generic exit code (125). This patch improves on this behavior and prevents any error from being printed when they match `context.Cancelled`. The `cli.StatusError` error would wrap errors but not provide a way to unwrap them. This would lead to situations where `errors.Is` would not match the underlying error. Signed-off-by: Alano Terblanche <[email protected]>
1 parent 5f22178 commit a20d0c8

File tree

14 files changed

+34
-27
lines changed

14 files changed

+34
-27
lines changed

cli/cobra.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func FlagErrorFunc(cmd *cobra.Command, err error) error {
9393
}
9494

9595
return StatusError{
96-
Status: fmt.Sprintf("%s\n\nUsage: %s\n\nRun '%s --help' for more information", err, cmd.UseLine(), cmd.CommandPath()),
96+
Cause: fmt.Errorf("%w\n\nUsage: %s\n\nRun '%s --help' for more information", err, cmd.UseLine(), cmd.CommandPath()),
9797
StatusCode: 125,
9898
}
9999
}

cli/command/config/inspect.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func RunConfigInspect(ctx context.Context, dockerCli command.Cli, opts InspectOp
6767
}
6868

6969
if err := InspectFormatWrite(configCtx, opts.Names, getRef); err != nil {
70-
return cli.StatusError{StatusCode: 1, Status: err.Error()}
70+
return cli.StatusError{StatusCode: 1, Cause: err}
7171
}
7272
return nil
7373
}

cli/command/container/create.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func NewCreateCommand(dockerCli command.Cli) *cobra.Command {
9393
func runCreate(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet, options *createOptions, copts *containerOptions) error {
9494
if err := validatePullOpt(options.pull); err != nil {
9595
return cli.StatusError{
96-
Status: withHelp(err, "create").Error(),
96+
Cause: withHelp(err, "create"),
9797
StatusCode: 125,
9898
}
9999
}
@@ -110,13 +110,13 @@ func runCreate(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet,
110110
containerCfg, err := parse(flags, copts, dockerCli.ServerInfo().OSType)
111111
if err != nil {
112112
return cli.StatusError{
113-
Status: withHelp(err, "create").Error(),
113+
Cause: withHelp(err, "create"),
114114
StatusCode: 125,
115115
}
116116
}
117117
if err = validateAPIVersion(containerCfg, dockerCli.Client().ClientVersion()); err != nil {
118118
return cli.StatusError{
119-
Status: withHelp(err, "create").Error(),
119+
Cause: withHelp(err, "create"),
120120
StatusCode: 125,
121121
}
122122
}

cli/command/container/run.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command {
8585
func runRun(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet, ropts *runOptions, copts *containerOptions) error {
8686
if err := validatePullOpt(ropts.pull); err != nil {
8787
return cli.StatusError{
88-
Status: withHelp(err, "run").Error(),
88+
Cause: withHelp(err, "run"),
8989
StatusCode: 125,
9090
}
9191
}
@@ -103,13 +103,13 @@ func runRun(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet, ro
103103
// just in case the parse does not exit
104104
if err != nil {
105105
return cli.StatusError{
106-
Status: withHelp(err, "run").Error(),
106+
Cause: withHelp(err, "run"),
107107
StatusCode: 125,
108108
}
109109
}
110110
if err = validateAPIVersion(containerCfg, dockerCli.CurrentVersion()); err != nil {
111111
return cli.StatusError{
112-
Status: withHelp(err, "run").Error(),
112+
Cause: withHelp(err, "run"),
113113
StatusCode: 125,
114114
}
115115
}
@@ -315,20 +315,20 @@ func toStatusError(err error) error {
315315

316316
if strings.Contains(errMsg, "executable file not found") || strings.Contains(errMsg, "no such file or directory") || strings.Contains(errMsg, "system cannot find the file specified") {
317317
return cli.StatusError{
318-
Status: withHelp(err, "run").Error(),
318+
Cause: withHelp(err, "run"),
319319
StatusCode: 127,
320320
}
321321
}
322322

323323
if strings.Contains(errMsg, syscall.EACCES.Error()) || strings.Contains(errMsg, syscall.EISDIR.Error()) {
324324
return cli.StatusError{
325-
Status: withHelp(err, "run").Error(),
325+
Cause: withHelp(err, "run"),
326326
StatusCode: 126,
327327
}
328328
}
329329

330330
return cli.StatusError{
331-
Status: withHelp(err, "run").Error(),
331+
Cause: withHelp(err, "run"),
332332
StatusCode: 125,
333333
}
334334
}

cli/command/container/run_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,10 @@ func TestRunPullTermination(t *testing.T) {
294294

295295
select {
296296
case cmdErr := <-cmdErrC:
297-
assert.Equal(t, cmdErr, cli.StatusError{
298-
StatusCode: 125,
299-
Status: "docker: context canceled\n\nRun 'docker run --help' for more information",
300-
})
297+
assert.ErrorIs(t, cmdErr, context.Canceled)
298+
v, ok := cmdErr.(cli.StatusError)
299+
assert.Check(t, ok)
300+
assert.Check(t, is.Equal(v.StatusCode, 125))
301301
case <-time.After(10 * time.Second):
302302
t.Fatal("cmd did not return before the timeout")
303303
}

cli/command/image/build.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
371371
if options.quiet {
372372
fmt.Fprintf(dockerCli.Err(), "%s%s", progBuff, buildBuff)
373373
}
374-
return cli.StatusError{Status: jerr.Message, StatusCode: jerr.Code}
374+
return cli.StatusError{Cause: jerr, StatusCode: jerr.Code}
375375
}
376376
return err
377377
}

cli/command/inspect/inspector.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ type GetRefFunc func(ref string) (any, []byte, error)
6767
func Inspect(out io.Writer, references []string, tmplStr string, getRef GetRefFunc) error {
6868
inspector, err := NewTemplateInspectorFromString(out, tmplStr)
6969
if err != nil {
70-
return cli.StatusError{StatusCode: 64, Status: err.Error()}
70+
return cli.StatusError{StatusCode: 64, Cause: err}
7171
}
7272

7373
var inspectErrs []string
@@ -90,7 +90,7 @@ func Inspect(out io.Writer, references []string, tmplStr string, getRef GetRefFu
9090
if len(inspectErrs) != 0 {
9191
return cli.StatusError{
9292
StatusCode: 1,
93-
Status: strings.Join(inspectErrs, "\n"),
93+
Cause: errors.New(strings.Join(inspectErrs, "\n")),
9494
}
9595
}
9696
return nil

cli/command/node/inspect.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions)
6969
}
7070

7171
if err := InspectFormatWrite(nodeCtx, opts.nodeIds, getRef); err != nil {
72-
return cli.StatusError{StatusCode: 1, Status: err.Error()}
72+
return cli.StatusError{StatusCode: 1, Cause: err}
7373
}
7474
return nil
7575
}

cli/command/secret/inspect.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func runSecretInspect(ctx context.Context, dockerCli command.Cli, opts inspectOp
6565
}
6666

6767
if err := InspectFormatWrite(secretCtx, opts.names, getRef); err != nil {
68-
return cli.StatusError{StatusCode: 1, Status: err.Error()}
68+
return cli.StatusError{StatusCode: 1, Cause: err}
6969
}
7070
return nil
7171
}

cli/command/service/inspect.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions)
9494
}
9595

9696
if err := InspectFormatWrite(serviceCtx, opts.refs, getRef, getNetwork); err != nil {
97-
return cli.StatusError{StatusCode: 1, Status: err.Error()}
97+
return cli.StatusError{StatusCode: 1, Cause: err}
9898
}
9999
return nil
100100
}

0 commit comments

Comments
 (0)