From 07d60bc2571ba3d680f21adc84d87803ab4959c6 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 17 Apr 2020 12:01:01 +0200 Subject: [PATCH] Replace errors.Cause() with errors.Is() / errors.As() Signed-off-by: Sebastiaan van Stijn --- builder/dockerfile/copy.go | 2 +- builder/remotecontext/detect.go | 2 +- builder/remotecontext/tarsum_test.go | 4 ++-- client/errors.go | 8 ++++---- container/container_unix.go | 4 ++-- daemon/attach.go | 3 ++- daemon/cluster/cluster.go | 2 +- daemon/cluster/executor/container/adapter.go | 11 ++++++++--- daemon/cluster/executor/container/controller.go | 3 ++- daemon/cluster/noderunner.go | 2 +- daemon/cluster/swarm.go | 4 ++-- daemon/daemon_test.go | 3 ++- daemon/graphdriver/aufs/aufs.go | 2 +- daemon/graphdriver/aufs/mount.go | 10 +++------- daemon/images/service.go | 2 +- daemon/logger/loggerutils/logfile.go | 6 +++--- integration-cli/docker_api_attach_test.go | 3 ++- integration-cli/docker_api_swarm_test.go | 3 +-- pkg/plugins/client_test.go | 6 +++--- pkg/plugins/plugin_test.go | 4 ++-- plugin/manager.go | 2 +- plugin/store.go | 5 +++-- volume/service/store.go | 4 ++-- 23 files changed, 50 insertions(+), 45 deletions(-) diff --git a/builder/dockerfile/copy.go b/builder/dockerfile/copy.go index 3e9980b472..d3613dcb3e 100644 --- a/builder/dockerfile/copy.go +++ b/builder/dockerfile/copy.go @@ -591,7 +591,7 @@ func endsInSlash(driver containerfs.Driver, path string) bool { func isExistingDirectory(point *copyEndpoint) (bool, error) { destStat, err := point.driver.Stat(point.path) switch { - case os.IsNotExist(err): + case errors.Is(err, os.ErrNotExist): return false, nil case err != nil: return false, err diff --git a/builder/remotecontext/detect.go b/builder/remotecontext/detect.go index 1becd0fd59..19580b01f8 100644 --- a/builder/remotecontext/detect.go +++ b/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) { df, err := openAt(c, dockerfilePath) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { if dockerfilePath == builder.DefaultDockerfileName { lowercase := strings.ToLower(dockerfilePath) if _, err := StatAt(c, lowercase); err == nil { diff --git a/builder/remotecontext/tarsum_test.go b/builder/remotecontext/tarsum_test.go index a98569f800..c6a417d7fd 100644 --- a/builder/remotecontext/tarsum_test.go +++ b/builder/remotecontext/tarsum_test.go @@ -38,7 +38,7 @@ func TestCloseRootDirectory(t *testing.T) { _, 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") } } @@ -131,7 +131,7 @@ func TestRemoveDirectory(t *testing.T) { } _, 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) } } diff --git a/client/errors.go b/client/errors.go index 001c102881..041bc8d49c 100644 --- a/client/errors.go +++ b/client/errors.go @@ -24,8 +24,7 @@ func (err errConnectionFailed) Error() string { // IsErrConnectionFailed returns true if the error is caused by connection failed. 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. @@ -42,8 +41,9 @@ type notFound interface { // IsErrNotFound returns true if the error is a NotFound error, which is returned // by the API when some object is not found. 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) } diff --git a/container/container_unix.go b/container/container_unix.go index 82f5693b10..8ab86121d9 100644 --- a/container/container_unix.go +++ b/container/container_unix.go @@ -190,7 +190,7 @@ func (container *Container) UnmountIpcMount() error { if shmPath == "" { 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 nil @@ -395,7 +395,7 @@ func (container *Container) DetachAndUnmount(volumeEventLog func(name, action st // are not supported func ignoreUnsupportedXAttrs() fs.CopyDirOpt { xeh := func(dst, src, xattrKey string, err error) error { - if errors.Cause(err) != syscall.ENOTSUP { + if !errors.Is(err, syscall.ENOTSUP) { return err } return nil diff --git a/daemon/attach.go b/daemon/attach.go index 5c3ceb8790..c6553f79d3 100644 --- a/daemon/attach.go +++ b/daemon/attach.go @@ -176,7 +176,8 @@ func (daemon *Daemon) containerAttach(c *container.Container, cfg *stream.Attach ctx := c.InitAttachContext() err := <-c.StreamConfig.CopyStreams(ctx, cfg) 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") } else { logrus.Errorf("attach failed with error: %v", err) diff --git a/daemon/cluster/cluster.go b/daemon/cluster/cluster.go index d3532a8736..c92df0983a 100644 --- a/daemon/cluster/cluster.go +++ b/daemon/cluster/cluster.go @@ -353,7 +353,7 @@ func (c *Cluster) currentNodeState() nodeState { // Call with read lock. func (c *Cluster) errNoManager(st nodeState) error { if st.swarmNode == nil { - if errors.Cause(st.err) == errSwarmLocked { + if errors.Is(st.err, errSwarmLocked) { return errSwarmLocked } if st.err == errSwarmCertificatesExpired { diff --git a/daemon/cluster/executor/container/adapter.go b/daemon/cluster/executor/container/adapter.go index 4b34615915..b9b42d02e5 100644 --- a/daemon/cluster/executor/container/adapter.go +++ b/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 { + var ( + activeEndpointsError *libnetwork.ActiveEndpointsError + errNoSuchNetwork libnetwork.ErrNoSuchNetwork + ) + for name, v := range c.container.networksAttachments { 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 - case libnetwork.ErrNoSuchNetwork: + case errors.As(err, &errNoSuchNetwork): continue default: log.G(ctx).Errorf("network %s remove failed: %v", name, err) diff --git a/daemon/cluster/executor/container/controller.go b/daemon/cluster/executor/container/controller.go index 56c23113e5..da7bd24746 100644 --- a/daemon/cluster/executor/container/controller.go +++ b/daemon/cluster/executor/container/controller.go @@ -204,9 +204,10 @@ func (r *controller) Start(ctx context.Context) error { return exec.ErrTaskStarted } + var lnErr libnetwork.ErrNoSuchNetwork for { 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 // failed because some of the networks // were not found. diff --git a/daemon/cluster/noderunner.go b/daemon/cluster/noderunner.go index 5246b14a1d..a25ce3feda 100644 --- a/daemon/cluster/noderunner.go +++ b/daemon/cluster/noderunner.go @@ -327,7 +327,7 @@ func (n *nodeRunner) State() nodeState { ns := n.nodeState if ns.err != nil || n.cancelReconnect != nil { - if errors.Cause(ns.err) == errSwarmLocked { + if errors.Is(ns.err, errSwarmLocked) { ns.status = types.LocalNodeStateLocked } else { ns.status = types.LocalNodeStateError diff --git a/daemon/cluster/swarm.go b/daemon/cluster/swarm.go index 8b471137a8..30418c7f68 100644 --- a/daemon/cluster/swarm.go +++ b/daemon/cluster/swarm.go @@ -347,7 +347,7 @@ func (c *Cluster) UnlockSwarm(req types.UnlockRequest) error { c.mu.Unlock() if err := <-nr.Ready(); err != nil { - if errors.Cause(err) == errSwarmLocked { + if errors.Is(err, errSwarmLocked) { return invalidUnlockKey{} } 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() - if errors.Cause(state.err) == errSwarmLocked && !force { + if errors.Is(state.err, errSwarmLocked) && !force { // 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.")) } diff --git a/daemon/daemon_test.go b/daemon/daemon_test.go index b34308db0a..c29b2705ba 100644 --- a/daemon/daemon_test.go +++ b/daemon/daemon_test.go @@ -312,7 +312,8 @@ func TestValidateContainerIsolation(t *testing.T) { func TestFindNetworkErrorType(t *testing.T) { d := Daemon{} _, err := d.FindNetwork("fakeNet") - _, ok := errors.Cause(err).(libnetwork.ErrNoSuchNetwork) + var nsn libnetwork.ErrNoSuchNetwork + ok := errors.As(err, &nsn) if !errdefs.IsNotFound(err) || !ok { t.Error("The FindNetwork method MUST always return an error that implements the NotFound interface and is ErrNoSuchNetwork") } diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go index 8396580f18..f87f673544 100644 --- a/daemon/graphdriver/aufs/aufs.go +++ b/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 // the whole tree. 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") } return errors.Wrapf(err, "could not remove mountpoint for id %s", id) diff --git a/daemon/graphdriver/aufs/mount.go b/daemon/graphdriver/aufs/mount.go index d6a760d1c2..029321e910 100644 --- a/daemon/graphdriver/aufs/mount.go +++ b/daemon/graphdriver/aufs/mount.go @@ -42,18 +42,14 @@ func Unmount(target string) error { var err error for i := 0; i < retries; i++ { 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) time.Sleep(100 * time.Millisecond) continue // try again - default: - // any other error is fatal - return err } + break } + // either no error occurred, or another error return err } diff --git a/daemon/images/service.go b/daemon/images/service.go index 142213c1a0..388aa2dd23 100644 --- a/daemon/images/service.go +++ b/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 { metadata, err := i.layerStores[containerOS].ReleaseRWLayer(rwlayer) 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", i.layerStores[containerOS].DriverName()) } diff --git a/daemon/logger/loggerutils/logfile.go b/daemon/logger/loggerutils/logfile.go index 88e2b5f6bb..1ac3381718 100644 --- a/daemon/logger/loggerutils/logfile.go +++ b/daemon/logger/loggerutils/logfile.go @@ -428,7 +428,7 @@ func (w *LogFile) openRotatedFiles(config logger.ReadConfig) (files []*os.File, }) 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") } continue @@ -533,7 +533,7 @@ func tailFiles(files []SizeReaderAt, watcher *logger.LogWatcher, dec Decoder, ge for { msg, err := dec.Decode() if err != nil { - if errors.Cause(err) != io.EOF { + if !errors.Is(err, io.EOF) { watcher.Err <- err } return @@ -633,7 +633,7 @@ func followLogs(f *os.File, logWatcher *logger.LogWatcher, notifyRotate chan int oldSize := int64(-1) handleDecodeErr := func(err error) error { - if errors.Cause(err) != io.EOF { + if !errors.Is(err, io.EOF) { return err } diff --git a/integration-cli/docker_api_attach_test.go b/integration-cli/docker_api_attach_test.go index 2627821cc1..0103ccab80 100644 --- a/integration-cli/docker_api_attach_test.go +++ b/integration-cli/docker_api_attach_test.go @@ -207,8 +207,9 @@ func (s *DockerSuite) TestPostContainersAttach(c *testing.T) { assert.NilError(c, err) var outBuf, errBuf bytes.Buffer + var nErr net.Error _, 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 err = nil } diff --git a/integration-cli/docker_api_swarm_test.go b/integration-cli/docker_api_swarm_test.go index f6b1aa9e71..e818b58e04 100644 --- a/integration-cli/docker_api_swarm_test.go +++ b/integration-cli/docker_api_swarm_test.go @@ -27,7 +27,6 @@ import ( testdaemon "github.com/docker/docker/testutil/daemon" "github.com/docker/docker/testutil/request" "github.com/docker/swarmkit/ca" - "github.com/pkg/errors" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" "gotest.tools/v3/poll" @@ -323,7 +322,7 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaderElection(c *testing.T) { followers = nil for _, d := range nodes { 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 return true } diff --git a/pkg/plugins/client_test.go b/pkg/plugins/client_test.go index 421d59c3e1..71a56145fd 100644 --- a/pkg/plugins/client_test.go +++ b/pkg/plugins/client_test.go @@ -253,9 +253,9 @@ func TestClientWithRequestTimeout(t *testing.T) { _, err := client.callWithRetry("/Plugin.Hello", nil, false, WithRequestTimeout(timeout)) 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 { diff --git a/pkg/plugins/plugin_test.go b/pkg/plugins/plugin_test.go index 76984ba271..7c7f745d29 100644 --- a/pkg/plugins/plugin_test.go +++ b/pkg/plugins/plugin_test.go @@ -77,11 +77,11 @@ func TestGet(t *testing.T) { // check negative case where plugin fruit doesn't implement 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 _, err = Get("vegetable", "potato") - assert.Equal(t, errors.Cause(err), ErrNotFound) + assert.Assert(t, errors.Is(err, ErrNotFound)) } func TestPluginWithNoManifest(t *testing.T) { diff --git a/plugin/manager.go b/plugin/manager.go index f67b22c952..17b17882e6 100644 --- a/plugin/manager.go +++ b/plugin/manager.go @@ -172,7 +172,7 @@ func handleLoadError(err error, id string) { return } 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 logger.Warn("missing plugin config, skipping: this may be caused due to a failed remove and requires manual cleanup.") return diff --git a/plugin/store.go b/plugin/store.go index 3c56a5cdc0..ecdf809d1f 100644 --- a/plugin/store.go +++ b/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 return nil, errDisabled(name) } - if _, ok := errors.Cause(err).(errNotFound); !ok { + var ierr errNotFound + if !errors.As(err, &ierr) { return nil, err } } @@ -166,7 +167,7 @@ func (ps *Store) Get(name, capability string, mode int) (plugingetter.CompatPlug if err == nil { return p, nil } - if errors.Cause(err) == plugins.ErrNotFound { + if errors.Is(err, plugins.ErrNotFound) { return nil, errNotFound(name) } return nil, errors.Wrap(errdefs.System(err), "legacy plugin") diff --git a/volume/service/store.go b/volume/service/store.go index b0163ec0aa..5183d1f7ab 100644 --- a/volume/service/store.go +++ b/volume/service/store.go @@ -743,8 +743,8 @@ func lookupVolume(ctx context.Context, store *drivers.Store, driverName, volumeN } v, err := vd.Get(volumeName) 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 { volumeName = v.Name() driverName = v.DriverName()