Better/more specific error messages on connect

Closes #15309

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2015-08-06 12:35:43 -04:00
parent 57c8f4244b
commit 9994a35b5d
3 changed files with 31 additions and 8 deletions

View File

@ -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

21
api/types/errors.go Normal file
View File

@ -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
}
}

View File

@ -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)