From 9994a35b5d4af281304b5146f88a225b9237712e Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Thu, 6 Aug 2015 12:35:43 -0400 Subject: [PATCH] Better/more specific error messages on connect Closes #15309 Signed-off-by: Brian Goff --- api/client/utils.go | 15 ++++++++------- api/types/errors.go | 21 +++++++++++++++++++++ registry/session.go | 3 ++- 3 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 api/types/errors.go diff --git a/api/client/utils.go b/api/client/utils.go index 8f8221551a..371092e7b9 100644 --- a/api/client/utils.go +++ b/api/client/utils.go @@ -30,7 +30,7 @@ import ( ) var ( - errConnectionRefused = errors.New("Cannot connect to the Docker daemon. Is 'docker -d' running on this host?") + errConnectionFailed = errors.New("Cannot connect to the Docker daemon. Is the docker daemon running on this host?") ) type serverResponse struct { @@ -94,13 +94,14 @@ func (cli *DockerCli) clientRequest(method, path string, in io.Reader, headers m if resp != nil { serverResp.statusCode = resp.StatusCode } + if err != nil { - if strings.Contains(err.Error(), "connection refused") { - return serverResp, errConnectionRefused + if types.IsTimeout(err) || strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "dial unix") { + return serverResp, errConnectionFailed } - if cli.tlsConfig == nil { - return serverResp, fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?\n* Is your docker daemon up and running?", err) + if cli.tlsConfig == nil && strings.Contains(err.Error(), "malformed HTTP response") { + return serverResp, fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err) } if cli.tlsConfig != nil && strings.Contains(err.Error(), "remote error: bad certificate") { return serverResp, fmt.Errorf("The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: %v", err) @@ -277,7 +278,7 @@ func getExitCode(cli *DockerCli, containerID string) (bool, int, error) { serverResp, err := cli.call("GET", "/containers/"+containerID+"/json", nil, nil) if err != nil { // If we can't connect, then the daemon probably died. - if err != errConnectionRefused { + if err != errConnectionFailed { return false, -1, err } return false, -1, nil @@ -299,7 +300,7 @@ func getExecExitCode(cli *DockerCli, execID string) (bool, int, error) { serverResp, err := cli.call("GET", "/exec/"+execID+"/json", nil, nil) if err != nil { // If we can't connect, then the daemon probably died. - if err != errConnectionRefused { + if err != errConnectionFailed { return false, -1, err } return false, -1, nil diff --git a/api/types/errors.go b/api/types/errors.go new file mode 100644 index 0000000000..c7a828f36d --- /dev/null +++ b/api/types/errors.go @@ -0,0 +1,21 @@ +package types + +import ( + "net" + "net/url" +) + +// IsTimeout takes an error returned from (generally) the http package and determines if it is a timeout error. +func IsTimeout(err error) bool { + switch e := err.(type) { + case net.Error: + return e.Timeout() + case *url.Error: + if t, ok := e.Err.(net.Error); ok { + return t.Timeout() + } + return false + default: + return false + } +} diff --git a/registry/session.go b/registry/session.go index a9c4daf3aa..d497cb956d 100644 --- a/registry/session.go +++ b/registry/session.go @@ -20,6 +20,7 @@ import ( "time" "github.com/Sirupsen/logrus" + "github.com/docker/docker/api/types" "github.com/docker/docker/cliconfig" "github.com/docker/docker/pkg/httputils" "github.com/docker/docker/pkg/ioutils" @@ -424,7 +425,7 @@ func (r *Session) GetRepositoryData(remote string) (*RepositoryData, error) { // and return a non-obtuse error message for users // "Get https://index.docker.io/v1/repositories/library/busybox/images: i/o timeout" // was a top search on the docker user forum - if strings.HasSuffix(err.Error(), "i/o timeout") { + if types.IsTimeout(err) { return nil, fmt.Errorf("Network timed out while trying to connect to %s. You may want to check your internet connection or if you are behind a proxy.", repositoryTarget) } return nil, fmt.Errorf("Error while pulling image: %v", err)