diff --git a/server/etcdserver/api/rafthttp/pipeline.go b/server/etcdserver/api/rafthttp/pipeline.go index 50b8c8dd3..0790b58d0 100644 --- a/server/etcdserver/api/rafthttp/pipeline.go +++ b/server/etcdserver/api/rafthttp/pipeline.go @@ -165,7 +165,7 @@ func (p *pipeline) post(data []byte) (err error) { p.picker.unreachable(u) // errMemberRemoved is a critical error since a removed member should // always be stopped. So we use reportCriticalError to report it to errorc. - if err == errMemberRemoved { + if errors.Is(err, errMemberRemoved) { reportCriticalError(err, p.errorc) } return err diff --git a/server/etcdserver/api/rafthttp/snapshot_sender.go b/server/etcdserver/api/rafthttp/snapshot_sender.go index 1f0253f14..07971cbbd 100644 --- a/server/etcdserver/api/rafthttp/snapshot_sender.go +++ b/server/etcdserver/api/rafthttp/snapshot_sender.go @@ -17,6 +17,7 @@ package rafthttp import ( "bytes" "context" + "errors" "io" "net/http" "time" @@ -110,7 +111,7 @@ func (s *snapshotSender) send(merged snap.Message) { // errMemberRemoved is a critical error since a removed member should // always be stopped. So we use reportCriticalError to report it to errorc. - if err == errMemberRemoved { + if errors.Is(err, errMemberRemoved) { reportCriticalError(err, s.errorc) } diff --git a/server/etcdserver/api/rafthttp/stream.go b/server/etcdserver/api/rafthttp/stream.go index 63ffe8fdc..7b73fcd00 100644 --- a/server/etcdserver/api/rafthttp/stream.go +++ b/server/etcdserver/api/rafthttp/stream.go @@ -16,6 +16,7 @@ package rafthttp import ( "context" + "errors" "fmt" "io" "net/http" @@ -428,7 +429,7 @@ func (cr *streamReader) run() { } switch { // all data is read out - case err == io.EOF: + case errors.Is(err, io.EOF): // connection is closed by the remote case transport.IsClosedConnError(err): default: diff --git a/server/etcdserver/api/v2discovery/discovery.go b/server/etcdserver/api/v2discovery/discovery.go index 5993d4458..fcdeb8290 100644 --- a/server/etcdserver/api/v2discovery/discovery.go +++ b/server/etcdserver/api/v2discovery/discovery.go @@ -187,7 +187,7 @@ func (d *discovery) joinCluster(config string) (string, error) { func (d *discovery) getCluster() (string, error) { nodes, size, index, err := d.checkCluster() if err != nil { - if err == ErrFullCluster { + if errors.Is(err, ErrFullCluster) { return nodesToCluster(nodes, size) } return "", err @@ -205,7 +205,8 @@ func (d *discovery) createSelf(contents string) error { resp, err := d.c.Create(ctx, d.selfKey(), contents) cancel() if err != nil { - if eerr, ok := err.(client.Error); ok && eerr.Code == client.ErrorCodeNodeExist { + var eerr client.Error + if errors.As(err, &eerr) && eerr.Code == client.ErrorCodeNodeExist { return ErrDuplicateID } return err @@ -224,13 +225,15 @@ func (d *discovery) checkCluster() ([]*client.Node, uint64, uint64, error) { resp, err := d.c.Get(ctx, path.Join(configKey, "size"), nil) cancel() if err != nil { - if eerr, ok := err.(*client.Error); ok && eerr.Code == client.ErrorCodeKeyNotFound { + var eerr *client.Error + if errors.As(err, &eerr) && eerr.Code == client.ErrorCodeKeyNotFound { return nil, 0, 0, ErrSizeNotFound } - if err == client.ErrInvalidJSON { + if errors.Is(err, client.ErrInvalidJSON) { return nil, 0, 0, ErrBadDiscoveryEndpoint } - if ce, ok := err.(*client.ClusterError); ok { + var ce *client.ClusterError + if errors.As(err, &ce) { d.lg.Warn( "failed to get from discovery server", zap.String("discovery-url", d.url.String()), @@ -251,7 +254,8 @@ func (d *discovery) checkCluster() ([]*client.Node, uint64, uint64, error) { resp, err = d.c.Get(ctx, d.cluster, nil) cancel() if err != nil { - if ce, ok := err.(*client.ClusterError); ok { + var ce *client.ClusterError + if errors.As(err, &ce) { d.lg.Warn( "failed to get from discovery server", zap.String("discovery-url", d.url.String()), diff --git a/server/etcdserver/api/v3rpc/lease.go b/server/etcdserver/api/v3rpc/lease.go index e03953935..4d215e630 100644 --- a/server/etcdserver/api/v3rpc/lease.go +++ b/server/etcdserver/api/v3rpc/lease.go @@ -16,6 +16,7 @@ package v3rpc import ( "context" + "errors" "io" "go.uber.org/zap" @@ -61,10 +62,10 @@ func (ls *LeaseServer) LeaseRevoke(ctx context.Context, rr *pb.LeaseRevokeReques func (ls *LeaseServer) LeaseTimeToLive(ctx context.Context, rr *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) { resp, err := ls.le.LeaseTimeToLive(ctx, rr) - if err != nil && err != lease.ErrLeaseNotFound { + if err != nil && !errors.Is(err, lease.ErrLeaseNotFound) { return nil, togRPCError(err) } - if err == lease.ErrLeaseNotFound { + if errors.Is(err, lease.ErrLeaseNotFound) { resp = &pb.LeaseTimeToLiveResponse{ Header: &pb.ResponseHeader{}, ID: rr.ID, @@ -80,7 +81,7 @@ func (ls *LeaseServer) LeaseLeases(ctx context.Context, rr *pb.LeaseLeasesReques if err != nil && !errors.Is(err, lease.ErrLeaseNotFound) { return nil, togRPCError(err) } - if err == lease.ErrLeaseNotFound { + if errors.Is(err, lease.ErrLeaseNotFound) { resp = &pb.LeaseLeasesResponse{ Header: &pb.ResponseHeader{}, Leases: []*pb.LeaseStatus{}, @@ -100,7 +101,7 @@ func (ls *LeaseServer) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) (err case <-stream.Context().Done(): // the only server-side cancellation is noleader for now. err = stream.Context().Err() - if err == context.Canceled { + if errors.Is(err, context.Canceled) { err = rpctypes.ErrGRPCNoLeader } } @@ -110,7 +111,7 @@ func (ls *LeaseServer) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) (err func (ls *LeaseServer) leaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) error { for { req, err := stream.Recv() - if err == io.EOF { + if errors.Is(err, io.EOF) { return nil } if err != nil { @@ -133,7 +134,7 @@ func (ls *LeaseServer) leaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) erro ls.hdr.fill(resp.Header) ttl, err := ls.le.LeaseRenew(stream.Context(), lease.LeaseID(req.ID)) - if err == lease.ErrLeaseNotFound { + if errors.Is(err, lease.ErrLeaseNotFound) { err = nil ttl = 0 } diff --git a/server/etcdserver/api/v3rpc/util.go b/server/etcdserver/api/v3rpc/util.go index a31e6cbec..2354b0cb2 100644 --- a/server/etcdserver/api/v3rpc/util.go +++ b/server/etcdserver/api/v3rpc/util.go @@ -16,6 +16,7 @@ package v3rpc import ( "context" + errorspkg "errors" "strings" "google.golang.org/grpc/codes" @@ -95,7 +96,7 @@ var toGRPCErrorMap = map[error]error{ func togRPCError(err error) error { // let gRPC server convert to codes.Canceled, codes.DeadlineExceeded - if err == context.Canceled || err == context.DeadlineExceeded { + if errorspkg.Is(err, context.Canceled) || errorspkg.Is(err, context.DeadlineExceeded) { return err } grpcErr, ok := toGRPCErrorMap[err] diff --git a/server/etcdserver/api/v3rpc/watch.go b/server/etcdserver/api/v3rpc/watch.go index 6e72b1ceb..2f0562960 100644 --- a/server/etcdserver/api/v3rpc/watch.go +++ b/server/etcdserver/api/v3rpc/watch.go @@ -16,6 +16,7 @@ package v3rpc import ( "context" + "errors" "io" "math/rand" "sync" @@ -211,13 +212,13 @@ func (ws *watchServer) Watch(stream pb.Watch_WatchServer) (err error) { // revisited. select { case err = <-errc: - if err == context.Canceled { + if errors.Is(err, context.Canceled) { err = rpctypes.ErrGRPCWatchCanceled } close(sws.ctrlStream) case <-stream.Context().Done(): err = stream.Context().Err() - if err == context.Canceled { + if errors.Is(err, context.Canceled) { err = rpctypes.ErrGRPCWatchCanceled } } @@ -241,7 +242,7 @@ func (sws *serverWatchStream) isWatchPermitted(wcr *pb.WatchCreateRequest) error func (sws *serverWatchStream) recvLoop() error { for { req, err := sws.gRPCStream.Recv() - if err == io.EOF { + if errors.Is(err, io.EOF) { return nil } if err != nil { diff --git a/server/etcdserver/apply/apply_auth_test.go b/server/etcdserver/apply/apply_auth_test.go index 6516f41b5..e7445a10a 100644 --- a/server/etcdserver/apply/apply_auth_test.go +++ b/server/etcdserver/apply/apply_auth_test.go @@ -16,6 +16,7 @@ package apply import ( "context" + "errors" "testing" "time" @@ -387,8 +388,8 @@ func TestAuthApplierV3_AdminPermission(t *testing.T) { tc.request.Header = &pb.RequestHeader{Username: userReadOnly} } result := authApplier.Apply(ctx, tc.request, dummyApplyFunc) - require.Equal(t, result.Err == auth.ErrPermissionDenied, tc.adminPermissionNeeded, - "Admin permission needed: got %v, expect: %v", result.Err == auth.ErrPermissionDenied, tc.adminPermissionNeeded) + require.Equal(t, errors.Is(result.Err, auth.ErrPermissionDenied), tc.adminPermissionNeeded, + "Admin permission needed: got %v, expect: %v", errors.Is(result.Err, auth.ErrPermissionDenied), tc.adminPermissionNeeded) }) } } diff --git a/server/lease/leasehttp/http.go b/server/lease/leasehttp/http.go index 5837ac40b..9592b63cb 100644 --- a/server/lease/leasehttp/http.go +++ b/server/lease/leasehttp/http.go @@ -75,7 +75,7 @@ func (h *leaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } ttl, rerr := h.l.Renew(lease.LeaseID(lreq.ID)) if rerr != nil { - if rerr == lease.ErrLeaseNotFound { + if errors.Is(rerr, lease.ErrLeaseNotFound) { http.Error(w, rerr.Error(), http.StatusNotFound) return } diff --git a/server/proxy/grpcproxy/lease.go b/server/proxy/grpcproxy/lease.go index fdc936ca9..dc42dc5a0 100644 --- a/server/proxy/grpcproxy/lease.go +++ b/server/proxy/grpcproxy/lease.go @@ -16,6 +16,7 @@ package grpcproxy import ( "context" + "errors" "io" "sync" "sync/atomic" @@ -245,7 +246,7 @@ type leaseProxyStream struct { func (lps *leaseProxyStream) recvLoop() error { for { rr, err := lps.stream.Recv() - if err == io.EOF { + if errors.Is(err, io.EOF) { return nil } if err != nil { diff --git a/server/proxy/grpcproxy/maintenance.go b/server/proxy/grpcproxy/maintenance.go index 50ecf67ff..553b66c4b 100644 --- a/server/proxy/grpcproxy/maintenance.go +++ b/server/proxy/grpcproxy/maintenance.go @@ -16,6 +16,7 @@ package grpcproxy import ( "context" + "errors" "io" pb "go.etcd.io/etcd/api/v3/etcdserverpb" @@ -50,7 +51,7 @@ func (mp *maintenanceProxy) Snapshot(sr *pb.SnapshotRequest, stream pb.Maintenan for { rr, err := sc.Recv() if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { return nil } return err diff --git a/server/storage/wal/decoder.go b/server/storage/wal/decoder.go index 0f47b72fd..01ffbd52b 100644 --- a/server/storage/wal/decoder.go +++ b/server/storage/wal/decoder.go @@ -16,6 +16,7 @@ package wal import ( "encoding/binary" + "errors" "fmt" "hash" "io" @@ -114,7 +115,7 @@ func (d *decoder) decodeRecord(rec *walpb.Record) error { if _, err = io.ReadFull(fileBufReader, data); err != nil { // ReadFull returns io.EOF only if no bytes were read // the decoder should treat this as an ErrUnexpectedEOF instead. - if err == io.EOF { + if errors.Is(err, io.EOF) { err = io.ErrUnexpectedEOF } return err