Browse Source

Replace errors.Cause() with errors.Is() / errors.As()

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 5 years ago
parent
commit
07d60bc257

+ 1 - 1
builder/dockerfile/copy.go

@@ -591,7 +591,7 @@ func endsInSlash(driver containerfs.Driver, path string) bool {
 func isExistingDirectory(point *copyEndpoint) (bool, error) {
 func isExistingDirectory(point *copyEndpoint) (bool, error) {
 	destStat, err := point.driver.Stat(point.path)
 	destStat, err := point.driver.Stat(point.path)
 	switch {
 	switch {
-	case os.IsNotExist(err):
+	case errors.Is(err, os.ErrNotExist):
 		return false, nil
 		return false, nil
 	case err != nil:
 	case err != nil:
 		return false, err
 		return false, err

+ 1 - 1
builder/remotecontext/detect.go

@@ -62,7 +62,7 @@ func newArchiveRemote(rc io.ReadCloser, dockerfilePath string) (builder.Source,
 func withDockerfileFromContext(c modifiableContext, dockerfilePath string) (builder.Source, *parser.Result, error) {
 func withDockerfileFromContext(c modifiableContext, dockerfilePath string) (builder.Source, *parser.Result, error) {
 	df, err := openAt(c, dockerfilePath)
 	df, err := openAt(c, dockerfilePath)
 	if err != nil {
 	if err != nil {
-		if os.IsNotExist(err) {
+		if errors.Is(err, os.ErrNotExist) {
 			if dockerfilePath == builder.DefaultDockerfileName {
 			if dockerfilePath == builder.DefaultDockerfileName {
 				lowercase := strings.ToLower(dockerfilePath)
 				lowercase := strings.ToLower(dockerfilePath)
 				if _, err := StatAt(c, lowercase); err == nil {
 				if _, err := StatAt(c, lowercase); err == nil {

+ 2 - 2
builder/remotecontext/tarsum_test.go

@@ -38,7 +38,7 @@ func TestCloseRootDirectory(t *testing.T) {
 
 
 	_, err = os.Stat(src.Root().Path())
 	_, err = os.Stat(src.Root().Path())
 
 
-	if !os.IsNotExist(err) {
+	if !errors.Is(err, os.ErrNotExist) {
 		t.Fatal("Directory should not exist at this point")
 		t.Fatal("Directory should not exist at this point")
 	}
 	}
 }
 }
@@ -131,7 +131,7 @@ func TestRemoveDirectory(t *testing.T) {
 	}
 	}
 
 
 	_, err = src.Root().Stat(src.Root().Join(src.Root().Path(), relativePath))
 	_, err = src.Root().Stat(src.Root().Join(src.Root().Path(), relativePath))
-	if !os.IsNotExist(errors.Cause(err)) {
+	if !errors.Is(err, os.ErrNotExist) {
 		t.Fatalf("Directory should not exist at this point: %+v ", err)
 		t.Fatalf("Directory should not exist at this point: %+v ", err)
 	}
 	}
 }
 }

+ 4 - 4
client/errors.go

@@ -24,8 +24,7 @@ func (err errConnectionFailed) Error() string {
 
 
 // IsErrConnectionFailed returns true if the error is caused by connection failed.
 // IsErrConnectionFailed returns true if the error is caused by connection failed.
 func IsErrConnectionFailed(err error) bool {
 func IsErrConnectionFailed(err error) bool {
-	_, ok := errors.Cause(err).(errConnectionFailed)
-	return ok
+	return errors.As(err, &errConnectionFailed{})
 }
 }
 
 
 // ErrorConnectionFailed returns an error with host in the error message when connection to docker daemon failed.
 // ErrorConnectionFailed returns an error with host in the error message when connection to docker daemon failed.
@@ -42,8 +41,9 @@ type notFound interface {
 // IsErrNotFound returns true if the error is a NotFound error, which is returned
 // IsErrNotFound returns true if the error is a NotFound error, which is returned
 // by the API when some object is not found.
 // by the API when some object is not found.
 func IsErrNotFound(err error) bool {
 func IsErrNotFound(err error) bool {
-	if _, ok := err.(notFound); ok {
-		return ok
+	var e notFound
+	if errors.As(err, &e) {
+		return true
 	}
 	}
 	return errdefs.IsNotFound(err)
 	return errdefs.IsNotFound(err)
 }
 }

+ 2 - 2
container/container_unix.go

@@ -190,7 +190,7 @@ func (container *Container) UnmountIpcMount() error {
 	if shmPath == "" {
 	if shmPath == "" {
 		return nil
 		return nil
 	}
 	}
-	if err = mount.Unmount(shmPath); err != nil && !os.IsNotExist(errors.Cause(err)) {
+	if err = mount.Unmount(shmPath); err != nil && !errors.Is(err, os.ErrNotExist) {
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil
@@ -395,7 +395,7 @@ func (container *Container) DetachAndUnmount(volumeEventLog func(name, action st
 // are not supported
 // are not supported
 func ignoreUnsupportedXAttrs() fs.CopyDirOpt {
 func ignoreUnsupportedXAttrs() fs.CopyDirOpt {
 	xeh := func(dst, src, xattrKey string, err error) error {
 	xeh := func(dst, src, xattrKey string, err error) error {
-		if errors.Cause(err) != syscall.ENOTSUP {
+		if !errors.Is(err, syscall.ENOTSUP) {
 			return err
 			return err
 		}
 		}
 		return nil
 		return nil

+ 2 - 1
daemon/attach.go

@@ -176,7 +176,8 @@ func (daemon *Daemon) containerAttach(c *container.Container, cfg *stream.Attach
 	ctx := c.InitAttachContext()
 	ctx := c.InitAttachContext()
 	err := <-c.StreamConfig.CopyStreams(ctx, cfg)
 	err := <-c.StreamConfig.CopyStreams(ctx, cfg)
 	if err != nil {
 	if err != nil {
-		if _, ok := errors.Cause(err).(term.EscapeError); ok || err == context.Canceled {
+		var ierr term.EscapeError
+		if errors.Is(err, context.Canceled) || errors.As(err, &ierr) {
 			daemon.LogContainerEvent(c, "detach")
 			daemon.LogContainerEvent(c, "detach")
 		} else {
 		} else {
 			logrus.Errorf("attach failed with error: %v", err)
 			logrus.Errorf("attach failed with error: %v", err)

+ 1 - 1
daemon/cluster/cluster.go

@@ -353,7 +353,7 @@ func (c *Cluster) currentNodeState() nodeState {
 // Call with read lock.
 // Call with read lock.
 func (c *Cluster) errNoManager(st nodeState) error {
 func (c *Cluster) errNoManager(st nodeState) error {
 	if st.swarmNode == nil {
 	if st.swarmNode == nil {
-		if errors.Cause(st.err) == errSwarmLocked {
+		if errors.Is(st.err, errSwarmLocked) {
 			return errSwarmLocked
 			return errSwarmLocked
 		}
 		}
 		if st.err == errSwarmCertificatesExpired {
 		if st.err == errSwarmCertificatesExpired {

+ 8 - 3
daemon/cluster/executor/container/adapter.go

@@ -222,12 +222,17 @@ func (c *containerAdapter) createNetworks(ctx context.Context) error {
 }
 }
 
 
 func (c *containerAdapter) removeNetworks(ctx context.Context) error {
 func (c *containerAdapter) removeNetworks(ctx context.Context) error {
+	var (
+		activeEndpointsError *libnetwork.ActiveEndpointsError
+		errNoSuchNetwork     libnetwork.ErrNoSuchNetwork
+	)
+
 	for name, v := range c.container.networksAttachments {
 	for name, v := range c.container.networksAttachments {
 		if err := c.backend.DeleteManagedNetwork(v.Network.ID); err != nil {
 		if err := c.backend.DeleteManagedNetwork(v.Network.ID); err != nil {
-			switch errors.Cause(err).(type) {
-			case *libnetwork.ActiveEndpointsError:
+			switch {
+			case errors.As(err, &activeEndpointsError):
 				continue
 				continue
-			case libnetwork.ErrNoSuchNetwork:
+			case errors.As(err, &errNoSuchNetwork):
 				continue
 				continue
 			default:
 			default:
 				log.G(ctx).Errorf("network %s remove failed: %v", name, err)
 				log.G(ctx).Errorf("network %s remove failed: %v", name, err)

+ 2 - 1
daemon/cluster/executor/container/controller.go

@@ -204,9 +204,10 @@ func (r *controller) Start(ctx context.Context) error {
 		return exec.ErrTaskStarted
 		return exec.ErrTaskStarted
 	}
 	}
 
 
+	var lnErr libnetwork.ErrNoSuchNetwork
 	for {
 	for {
 		if err := r.adapter.start(ctx); err != nil {
 		if err := r.adapter.start(ctx); err != nil {
-			if _, ok := errors.Cause(err).(libnetwork.ErrNoSuchNetwork); ok {
+			if errors.As(err, &lnErr) {
 				// Retry network creation again if we
 				// Retry network creation again if we
 				// failed because some of the networks
 				// failed because some of the networks
 				// were not found.
 				// were not found.

+ 1 - 1
daemon/cluster/noderunner.go

@@ -327,7 +327,7 @@ func (n *nodeRunner) State() nodeState {
 	ns := n.nodeState
 	ns := n.nodeState
 
 
 	if ns.err != nil || n.cancelReconnect != nil {
 	if ns.err != nil || n.cancelReconnect != nil {
-		if errors.Cause(ns.err) == errSwarmLocked {
+		if errors.Is(ns.err, errSwarmLocked) {
 			ns.status = types.LocalNodeStateLocked
 			ns.status = types.LocalNodeStateLocked
 		} else {
 		} else {
 			ns.status = types.LocalNodeStateError
 			ns.status = types.LocalNodeStateError

+ 2 - 2
daemon/cluster/swarm.go

@@ -347,7 +347,7 @@ func (c *Cluster) UnlockSwarm(req types.UnlockRequest) error {
 	c.mu.Unlock()
 	c.mu.Unlock()
 
 
 	if err := <-nr.Ready(); err != nil {
 	if err := <-nr.Ready(); err != nil {
-		if errors.Cause(err) == errSwarmLocked {
+		if errors.Is(err, errSwarmLocked) {
 			return invalidUnlockKey{}
 			return invalidUnlockKey{}
 		}
 		}
 		return errors.Errorf("swarm component could not be started: %v", err)
 		return errors.Errorf("swarm component could not be started: %v", err)
@@ -371,7 +371,7 @@ func (c *Cluster) Leave(force bool) error {
 
 
 	c.mu.Unlock()
 	c.mu.Unlock()
 
 
-	if errors.Cause(state.err) == errSwarmLocked && !force {
+	if errors.Is(state.err, errSwarmLocked) && !force {
 		// leave a locked swarm without --force is not allowed
 		// leave a locked swarm without --force is not allowed
 		return errors.WithStack(notAvailableError("Swarm is encrypted and locked. Please unlock it first or use `--force` to ignore this message."))
 		return errors.WithStack(notAvailableError("Swarm is encrypted and locked. Please unlock it first or use `--force` to ignore this message."))
 	}
 	}

+ 2 - 1
daemon/daemon_test.go

@@ -312,7 +312,8 @@ func TestValidateContainerIsolation(t *testing.T) {
 func TestFindNetworkErrorType(t *testing.T) {
 func TestFindNetworkErrorType(t *testing.T) {
 	d := Daemon{}
 	d := Daemon{}
 	_, err := d.FindNetwork("fakeNet")
 	_, err := d.FindNetwork("fakeNet")
-	_, ok := errors.Cause(err).(libnetwork.ErrNoSuchNetwork)
+	var nsn libnetwork.ErrNoSuchNetwork
+	ok := errors.As(err, &nsn)
 	if !errdefs.IsNotFound(err) || !ok {
 	if !errdefs.IsNotFound(err) || !ok {
 		t.Error("The FindNetwork method MUST always return an error that implements the NotFound interface and is ErrNoSuchNetwork")
 		t.Error("The FindNetwork method MUST always return an error that implements the NotFound interface and is ErrNoSuchNetwork")
 	}
 	}

+ 1 - 1
daemon/graphdriver/aufs/aufs.go

@@ -324,7 +324,7 @@ func (a *Driver) Remove(id string) error {
 	// way (so that docker doesn't find it anymore) before doing removal of
 	// way (so that docker doesn't find it anymore) before doing removal of
 	// the whole tree.
 	// the whole tree.
 	if err := atomicRemove(mountpoint); err != nil {
 	if err := atomicRemove(mountpoint); err != nil {
-		if errors.Cause(err) == unix.EBUSY {
+		if errors.Is(err, unix.EBUSY) {
 			logger.WithField("dir", mountpoint).WithError(err).Warn("error performing atomic remove due to EBUSY")
 			logger.WithField("dir", mountpoint).WithError(err).Warn("error performing atomic remove due to EBUSY")
 		}
 		}
 		return errors.Wrapf(err, "could not remove mountpoint for id %s", id)
 		return errors.Wrapf(err, "could not remove mountpoint for id %s", id)

+ 3 - 7
daemon/graphdriver/aufs/mount.go

@@ -42,18 +42,14 @@ func Unmount(target string) error {
 	var err error
 	var err error
 	for i := 0; i < retries; i++ {
 	for i := 0; i < retries; i++ {
 		err = mount.Unmount(target)
 		err = mount.Unmount(target)
-		switch errors.Cause(err) {
-		case nil:
-			return nil
-		case unix.EBUSY:
+		if err != nil && errors.Is(err, unix.EBUSY) {
 			logger.Debugf("aufs unmount %s failed with EBUSY (retrying %d/%d)", target, i+1, retries)
 			logger.Debugf("aufs unmount %s failed with EBUSY (retrying %d/%d)", target, i+1, retries)
 			time.Sleep(100 * time.Millisecond)
 			time.Sleep(100 * time.Millisecond)
 			continue // try again
 			continue // try again
-		default:
-			// any other error is fatal
-			return err
 		}
 		}
+		break
 	}
 	}
 
 
+	// either no error occurred, or another error
 	return err
 	return err
 }
 }

+ 1 - 1
daemon/images/service.go

@@ -184,7 +184,7 @@ func (i *ImageService) GraphDriverForOS(os string) string {
 func (i *ImageService) ReleaseLayer(rwlayer layer.RWLayer, containerOS string) error {
 func (i *ImageService) ReleaseLayer(rwlayer layer.RWLayer, containerOS string) error {
 	metadata, err := i.layerStores[containerOS].ReleaseRWLayer(rwlayer)
 	metadata, err := i.layerStores[containerOS].ReleaseRWLayer(rwlayer)
 	layer.LogReleaseMetadata(metadata)
 	layer.LogReleaseMetadata(metadata)
-	if err != nil && err != layer.ErrMountDoesNotExist && !os.IsNotExist(errors.Cause(err)) {
+	if err != nil && !errors.Is(err, layer.ErrMountDoesNotExist) && !errors.Is(err, os.ErrNotExist) {
 		return errors.Wrapf(err, "driver %q failed to remove root filesystem",
 		return errors.Wrapf(err, "driver %q failed to remove root filesystem",
 			i.layerStores[containerOS].DriverName())
 			i.layerStores[containerOS].DriverName())
 	}
 	}

+ 3 - 3
daemon/logger/loggerutils/logfile.go

@@ -428,7 +428,7 @@ func (w *LogFile) openRotatedFiles(config logger.ReadConfig) (files []*os.File,
 			})
 			})
 
 
 			if err != nil {
 			if err != nil {
-				if !os.IsNotExist(errors.Cause(err)) {
+				if !errors.Is(err, os.ErrNotExist) {
 					return nil, errors.Wrap(err, "error getting reference to decompressed log file")
 					return nil, errors.Wrap(err, "error getting reference to decompressed log file")
 				}
 				}
 				continue
 				continue
@@ -533,7 +533,7 @@ func tailFiles(files []SizeReaderAt, watcher *logger.LogWatcher, dec Decoder, ge
 	for {
 	for {
 		msg, err := dec.Decode()
 		msg, err := dec.Decode()
 		if err != nil {
 		if err != nil {
-			if errors.Cause(err) != io.EOF {
+			if !errors.Is(err, io.EOF) {
 				watcher.Err <- err
 				watcher.Err <- err
 			}
 			}
 			return
 			return
@@ -633,7 +633,7 @@ func followLogs(f *os.File, logWatcher *logger.LogWatcher, notifyRotate chan int
 
 
 	oldSize := int64(-1)
 	oldSize := int64(-1)
 	handleDecodeErr := func(err error) error {
 	handleDecodeErr := func(err error) error {
-		if errors.Cause(err) != io.EOF {
+		if !errors.Is(err, io.EOF) {
 			return err
 			return err
 		}
 		}
 
 

+ 2 - 1
integration-cli/docker_api_attach_test.go

@@ -207,8 +207,9 @@ func (s *DockerSuite) TestPostContainersAttach(c *testing.T) {
 	assert.NilError(c, err)
 	assert.NilError(c, err)
 
 
 	var outBuf, errBuf bytes.Buffer
 	var outBuf, errBuf bytes.Buffer
+	var nErr net.Error
 	_, err = stdcopy.StdCopy(&outBuf, &errBuf, resp.Reader)
 	_, err = stdcopy.StdCopy(&outBuf, &errBuf, resp.Reader)
-	if err != nil && errors.Cause(err).(net.Error).Timeout() {
+	if errors.As(err, &nErr) && nErr.Timeout() {
 		// ignore the timeout error as it is expected
 		// ignore the timeout error as it is expected
 		err = nil
 		err = nil
 	}
 	}

+ 1 - 2
integration-cli/docker_api_swarm_test.go

@@ -27,7 +27,6 @@ import (
 	testdaemon "github.com/docker/docker/testutil/daemon"
 	testdaemon "github.com/docker/docker/testutil/daemon"
 	"github.com/docker/docker/testutil/request"
 	"github.com/docker/docker/testutil/request"
 	"github.com/docker/swarmkit/ca"
 	"github.com/docker/swarmkit/ca"
-	"github.com/pkg/errors"
 	"gotest.tools/v3/assert"
 	"gotest.tools/v3/assert"
 	is "gotest.tools/v3/assert/cmp"
 	is "gotest.tools/v3/assert/cmp"
 	"gotest.tools/v3/poll"
 	"gotest.tools/v3/poll"
@@ -323,7 +322,7 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaderElection(c *testing.T) {
 			followers = nil
 			followers = nil
 			for _, d := range nodes {
 			for _, d := range nodes {
 				n := d.GetNode(c, d.NodeID(), func(err error) bool {
 				n := d.GetNode(c, d.NodeID(), func(err error) bool {
-					if strings.Contains(errors.Cause(err).Error(), context.DeadlineExceeded.Error()) || strings.Contains(err.Error(), "swarm does not have a leader") {
+					if strings.Contains(err.Error(), context.DeadlineExceeded.Error()) || strings.Contains(err.Error(), "swarm does not have a leader") {
 						lastErr = err
 						lastErr = err
 						return true
 						return true
 					}
 					}

+ 3 - 3
pkg/plugins/client_test.go

@@ -253,9 +253,9 @@ func TestClientWithRequestTimeout(t *testing.T) {
 	_, err := client.callWithRetry("/Plugin.Hello", nil, false, WithRequestTimeout(timeout))
 	_, err := client.callWithRetry("/Plugin.Hello", nil, false, WithRequestTimeout(timeout))
 	assert.Assert(t, is.ErrorContains(err, ""), "expected error")
 	assert.Assert(t, is.ErrorContains(err, ""), "expected error")
 
 
-	err = errors.Cause(err)
-	assert.ErrorType(t, err, (*timeoutError)(nil))
-	assert.Equal(t, err.(timeoutError).Timeout(), true)
+	var tErr timeoutError
+	assert.Assert(t, errors.As(err, &tErr))
+	assert.Assert(t, tErr.Timeout())
 }
 }
 
 
 type testRequestWrapper struct {
 type testRequestWrapper struct {

+ 2 - 2
pkg/plugins/plugin_test.go

@@ -77,11 +77,11 @@ func TestGet(t *testing.T) {
 
 
 	// check negative case where plugin fruit doesn't implement banana
 	// check negative case where plugin fruit doesn't implement banana
 	_, err = Get("fruit", "banana")
 	_, err = Get("fruit", "banana")
-	assert.Equal(t, errors.Cause(err), ErrNotImplements)
+	assert.Assert(t, errors.Is(err, ErrNotImplements))
 
 
 	// check negative case where plugin vegetable doesn't exist
 	// check negative case where plugin vegetable doesn't exist
 	_, err = Get("vegetable", "potato")
 	_, err = Get("vegetable", "potato")
-	assert.Equal(t, errors.Cause(err), ErrNotFound)
+	assert.Assert(t, errors.Is(err, ErrNotFound))
 }
 }
 
 
 func TestPluginWithNoManifest(t *testing.T) {
 func TestPluginWithNoManifest(t *testing.T) {

+ 1 - 1
plugin/manager.go

@@ -172,7 +172,7 @@ func handleLoadError(err error, id string) {
 		return
 		return
 	}
 	}
 	logger := logrus.WithError(err).WithField("id", id)
 	logger := logrus.WithError(err).WithField("id", id)
-	if os.IsNotExist(errors.Cause(err)) {
+	if errors.Is(err, os.ErrNotExist) {
 		// Likely some error while removing on an older version of docker
 		// Likely some error while removing on an older version of docker
 		logger.Warn("missing plugin config, skipping: this may be caused due to a failed remove and requires manual cleanup.")
 		logger.Warn("missing plugin config, skipping: this may be caused due to a failed remove and requires manual cleanup.")
 		return
 		return

+ 3 - 2
plugin/store.go

@@ -153,7 +153,8 @@ func (ps *Store) Get(name, capability string, mode int) (plugingetter.CompatPlug
 			// but we should error out right away
 			// but we should error out right away
 			return nil, errDisabled(name)
 			return nil, errDisabled(name)
 		}
 		}
-		if _, ok := errors.Cause(err).(errNotFound); !ok {
+		var ierr errNotFound
+		if !errors.As(err, &ierr) {
 			return nil, err
 			return nil, err
 		}
 		}
 	}
 	}
@@ -166,7 +167,7 @@ func (ps *Store) Get(name, capability string, mode int) (plugingetter.CompatPlug
 	if err == nil {
 	if err == nil {
 		return p, nil
 		return p, nil
 	}
 	}
-	if errors.Cause(err) == plugins.ErrNotFound {
+	if errors.Is(err, plugins.ErrNotFound) {
 		return nil, errNotFound(name)
 		return nil, errNotFound(name)
 	}
 	}
 	return nil, errors.Wrap(errdefs.System(err), "legacy plugin")
 	return nil, errors.Wrap(errdefs.System(err), "legacy plugin")

+ 2 - 2
volume/service/store.go

@@ -743,8 +743,8 @@ func lookupVolume(ctx context.Context, store *drivers.Store, driverName, volumeN
 	}
 	}
 	v, err := vd.Get(volumeName)
 	v, err := vd.Get(volumeName)
 	if err != nil {
 	if err != nil {
-		err = errors.Cause(err)
-		if _, ok := err.(net.Error); ok {
+		var nErr net.Error
+		if errors.As(err, &nErr) {
 			if v != nil {
 			if v != nil {
 				volumeName = v.Name()
 				volumeName = v.Name()
 				driverName = v.DriverName()
 				driverName = v.DriverName()