@@ -22,6 +22,7 @@ import (
2222 "github.com/docker/cli/templates"
2323 "github.com/docker/docker/api/types/swarm"
2424 "github.com/docker/docker/api/types/system"
25+ "github.com/docker/docker/client"
2526 "github.com/docker/docker/registry"
2627 "github.com/docker/go-units"
2728 "github.com/spf13/cobra"
@@ -97,30 +98,45 @@ func runInfo(ctx context.Context, cmd *cobra.Command, dockerCli command.Cli, opt
9798 info .ClientErrors = append (info .ClientErrors , err .Error ())
9899 }
99100
101+ var serverConnErr error
100102 if needsServerInfo (opts .format , info ) {
101- if dinfo , err := dockerCli .Client ().Info (ctx ); err == nil {
102- info .Info = & dinfo
103- } else {
104- info .ServerErrors = append (info .ServerErrors , err .Error ())
105- if opts .format == "" {
106- // reset the server info to prevent printing "empty" Server info
107- // and warnings, but don't reset it if a custom format was specified
108- // to prevent errors from Go's template parsing during format.
109- info .Info = nil
110- } else {
111- // if a format is provided, print the error, as it may be hidden
112- // otherwise if the template doesn't include the ServerErrors field.
113- fprintln (dockerCli .Err (), err )
114- }
115- }
103+ serverConnErr = addServerInfo (ctx , dockerCli , opts .format , & info )
116104 }
117105
118106 if opts .format == "" {
119107 info .UserName = dockerCli .ConfigFile ().AuthConfigs [registry .IndexServer ].Username
120108 info .ClientInfo .APIVersion = dockerCli .CurrentVersion ()
121- return prettyPrintInfo (dockerCli , info )
109+ return errors . Join ( prettyPrintInfo (dockerCli , info ), serverConnErr )
122110 }
123- return formatInfo (dockerCli .Out (), info , opts .format )
111+
112+ return errors .Join (serverConnErr , formatInfo (dockerCli .Out (), info , opts .format ))
113+ }
114+
115+ // addServerInfo retrieves the server information and adds it to the dockerInfo struct.
116+ // if a connection error occurs, it will be returned as an error.
117+ // other errors are appended to the info.ServerErrors field.
118+ func addServerInfo (ctx context.Context , dockerCli command.Cli , format string , info * dockerInfo ) error {
119+ dinfo , err := dockerCli .Client ().Info (ctx )
120+ if err != nil {
121+ // if no format is provided and we have an error, don't print the server info
122+ if format == "" {
123+ info .Info = nil
124+ }
125+ if ! client .IsErrConnectionFailed (err ) {
126+ info .ServerErrors = append (info .ServerErrors , err .Error ())
127+ if format != "" {
128+ fprintln (dockerCli .Err (), err )
129+ }
130+ return nil
131+ }
132+ // on a server connection error, we want to return an error
133+ // with a status code of 255.
134+ return cli.StatusError {StatusCode : 255 , Cause : err }
135+ }
136+
137+ // only assign the server info if we have no error
138+ info .Info = & dinfo
139+ return nil
124140}
125141
126142// placeHolders does a rudimentary match for possible placeholders in a
0 commit comments