diff --git a/pkg/acceptance/cluster/docker.go b/pkg/acceptance/cluster/docker.go index fe8a0cf409af..214caa6ee6ca 100644 --- a/pkg/acceptance/cluster/docker.go +++ b/pkg/acceptance/cluster/docker.go @@ -388,7 +388,7 @@ func (cli resilientDockerClient) ContainerStart( // Keep going if ContainerStart timed out, but client's context is not // expired. - if errors.Cause(err) == context.DeadlineExceeded && clientCtx.Err() == nil { + if errors.Is(err, context.DeadlineExceeded) && clientCtx.Err() == nil { log.Warningf(clientCtx, "ContainerStart timed out, retrying") continue } diff --git a/pkg/ccl/importccl/load.go b/pkg/ccl/importccl/load.go index 43ef6e469802..6244f57a4137 100644 --- a/pkg/ccl/importccl/load.go +++ b/pkg/ccl/importccl/load.go @@ -74,7 +74,7 @@ func getDescriptorFromDB( keys.RootNamespaceID, dbName, ).Scan(&dbDescBytes); err != nil { - if err == gosql.ErrNoRows { + if errors.Is(err, gosql.ErrNoRows) { continue } return nil, errors.Wrap(err, "fetch database descriptor") diff --git a/pkg/ccl/importccl/read_import_mysql.go b/pkg/ccl/importccl/read_import_mysql.go index 3fe97f98903d..ac0de39b1638 100644 --- a/pkg/ccl/importccl/read_import_mysql.go +++ b/pkg/ccl/importccl/read_import_mysql.go @@ -110,7 +110,7 @@ func (m *mysqldumpReader) readFile( if err == io.EOF { break } - if err == mysql.ErrEmpty { + if errors.Is(err, mysql.ErrEmpty) { continue } if err != nil { @@ -300,7 +300,7 @@ func readMysqlCreateTable( if err == io.EOF { break } - if err == mysql.ErrEmpty { + if errors.Is(err, mysql.ErrEmpty) { continue } if err != nil { diff --git a/pkg/ccl/importccl/read_import_pgcopy.go b/pkg/ccl/importccl/read_import_pgcopy.go index 8452e83ebacf..1adf3d00421b 100644 --- a/pkg/ccl/importccl/read_import_pgcopy.go +++ b/pkg/ccl/importccl/read_import_pgcopy.go @@ -166,7 +166,7 @@ func (p *postgreStreamCopy) Next() (copyData, error) { // Attempt to read an entire line. scanned := p.s.Scan() if err := p.s.Err(); err != nil { - if err == bufio.ErrTooLong { + if errors.Is(err, bufio.ErrTooLong) { err = errors.New("line too long") } return nil, err diff --git a/pkg/ccl/importccl/read_import_pgdump.go b/pkg/ccl/importccl/read_import_pgdump.go index e7cb26f475b9..d882b5795c60 100644 --- a/pkg/ccl/importccl/read_import_pgdump.go +++ b/pkg/ccl/importccl/read_import_pgdump.go @@ -78,7 +78,7 @@ func splitSQLSemicolon(data []byte, atEOF bool) (advance int, token []byte, err func (p *postgreStream) Next() (interface{}, error) { if p.copy != nil { row, err := p.copy.Next() - if err == errCopyDone { + if errors.Is(err, errCopyDone) { p.copy = nil return errCopyDone, nil } @@ -125,8 +125,8 @@ func (p *postgreStream) Next() (interface{}, error) { } } if err := p.s.Err(); err != nil { - if err == bufio.ErrTooLong { - err = errors.New("line too long") + if errors.Is(err, bufio.ErrTooLong) { + err = errors.HandledWithMessage(err, "line too long") } return nil, err } diff --git a/pkg/ccl/workloadccl/fixture.go b/pkg/ccl/workloadccl/fixture.go index b74e0ca92aa6..5b350e3b85f2 100644 --- a/pkg/ccl/workloadccl/fixture.go +++ b/pkg/ccl/workloadccl/fixture.go @@ -142,7 +142,7 @@ func GetFixture( fixtureFolder := generatorToGCSFolder(config, gen) _, err := b.Objects(ctx, &storage.Query{Prefix: fixtureFolder, Delimiter: `/`}).Next() - if err == iterator.Done { + if errors.Is(err, iterator.Done) { notFound = true return errors.Errorf(`fixture not found: %s`, fixtureFolder) } else if err != nil { @@ -153,7 +153,7 @@ func GetFixture( for _, table := range gen.Tables() { tableFolder := filepath.Join(fixtureFolder, table.Name) _, err := b.Objects(ctx, &storage.Query{Prefix: tableFolder, Delimiter: `/`}).Next() - if err == iterator.Done { + if errors.Is(err, iterator.Done) { return errors.Errorf(`fixture table not found: %s`, tableFolder) } else if err != nil { return err @@ -619,14 +619,14 @@ func ListFixtures( gensPrefix := config.GCSPrefix + `/` for genIter := b.Objects(ctx, &storage.Query{Prefix: gensPrefix, Delimiter: `/`}); ; { gen, err := genIter.Next() - if err == iterator.Done { + if errors.Is(err, iterator.Done) { break } else if err != nil { return nil, err } for genConfigIter := b.Objects(ctx, &storage.Query{Prefix: gen.Prefix, Delimiter: `/`}); ; { genConfig, err := genConfigIter.Next() - if err == iterator.Done { + if errors.Is(err, iterator.Done) { break } else if err != nil { return nil, err diff --git a/pkg/cli/sql.go b/pkg/cli/sql.go index 1460ab41a69b..b9294a88eaee 100644 --- a/pkg/cli/sql.go +++ b/pkg/cli/sql.go @@ -1349,7 +1349,7 @@ func (c *cliState) configurePreShellDefaults() (cleanupFn func(), err error) { c.ins, c.exitErr = readline.InitFiles("cockroach", true, /* wideChars */ stdin, os.Stdout, stderr) - if c.exitErr == readline.ErrWidecharNotSupported { + if errors.Is(c.exitErr, readline.ErrWidecharNotSupported) { log.Warning(context.TODO(), "wide character support disabled") c.ins, c.exitErr = readline.InitFiles("cockroach", false, stdin, os.Stdout, stderr) diff --git a/pkg/cli/sql_util.go b/pkg/cli/sql_util.go index eba10df818a4..e5b0dee14a25 100644 --- a/pkg/cli/sql_util.go +++ b/pkg/cli/sql_util.go @@ -173,7 +173,7 @@ func (c *sqlConn) getServerMetadata() ( ) { // Retrieve the node ID and server build info. rows, err := c.Query("SELECT * FROM crdb_internal.node_build_info", nil) - if err == driver.ErrBadConn { + if errors.Is(err, driver.ErrBadConn) { return 0, "", "", err } if err != nil { @@ -241,7 +241,7 @@ func (c *sqlConn) checkServerMetadata() error { } _, newServerVersion, newClusterID, err := c.getServerMetadata() - if err == driver.ErrBadConn { + if errors.Is(err, driver.ErrBadConn) { return err } if err != nil { @@ -394,7 +394,7 @@ func (c *sqlConn) Exec(query string, args []driver.Value) error { } _, err := c.conn.Exec(query, args) c.flushNotices() - if err == driver.ErrBadConn { + if errors.Is(err, driver.ErrBadConn) { c.reconnecting = true c.Close() } @@ -409,7 +409,7 @@ func (c *sqlConn) Query(query string, args []driver.Value) (*sqlRows, error) { fmt.Fprintln(stderr, ">", query) } rows, err := c.conn.Query(query, args) - if err == driver.ErrBadConn { + if errors.Is(err, driver.ErrBadConn) { c.reconnecting = true c.Close() } @@ -447,7 +447,7 @@ func (c *sqlConn) Close() { c.flushNotices() if c.conn != nil { err := c.conn.Close() - if err != nil && err != driver.ErrBadConn { + if err != nil && !errors.Is(err, driver.ErrBadConn) { log.Infof(context.TODO(), "%v", err) } c.conn = nil @@ -485,7 +485,7 @@ func (r *sqlRows) Tag() string { func (r *sqlRows) Close() error { r.conn.flushNotices() err := r.rows.Close() - if err == driver.ErrBadConn { + if errors.Is(err, driver.ErrBadConn) { r.conn.reconnecting = true r.conn.Close() } @@ -498,7 +498,7 @@ func (r *sqlRows) Close() error { // (since this is unobvious and unexpected behavior) outweigh. func (r *sqlRows) Next(values []driver.Value) error { err := r.rows.Next(values) - if err == driver.ErrBadConn { + if errors.Is(err, driver.ErrBadConn) { r.conn.reconnecting = true r.conn.Close() } diff --git a/pkg/cli/sql_util_test.go b/pkg/cli/sql_util_test.go index 554329976626..9bf51f691ba6 100644 --- a/pkg/cli/sql_util_test.go +++ b/pkg/cli/sql_util_test.go @@ -22,6 +22,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" "github.com/cockroachdb/cockroach/pkg/util/leaktest" + "github.com/cockroachdb/errors" ) func TestConnRecover(t *testing.T) { @@ -54,7 +55,7 @@ func TestConnRecover(t *testing.T) { // and starts delivering ErrBadConn. We don't know the timing of // this however. testutils.SucceedsSoon(t, func() error { - if sqlRows, err := conn.Query(`SELECT 1`, nil); err != driver.ErrBadConn { + if sqlRows, err := conn.Query(`SELECT 1`, nil); !errors.Is(err, driver.ErrBadConn) { return fmt.Errorf("expected ErrBadConn, got %v", err) } else if err == nil { if closeErr := sqlRows.Close(); closeErr != nil { @@ -78,7 +79,7 @@ func TestConnRecover(t *testing.T) { // Ditto from Query(). testutils.SucceedsSoon(t, func() error { - if err := conn.Exec(`SELECT 1`, nil); err != driver.ErrBadConn { + if err := conn.Exec(`SELECT 1`, nil); !errors.Is(err, driver.ErrBadConn) { return fmt.Errorf("expected ErrBadConn, got %v", err) } return nil diff --git a/pkg/cmd/cr2pg/sqlstream/stream.go b/pkg/cmd/cr2pg/sqlstream/stream.go index 22c8d9e1cc65..5f69f782d017 100644 --- a/pkg/cmd/cr2pg/sqlstream/stream.go +++ b/pkg/cmd/cr2pg/sqlstream/stream.go @@ -74,8 +74,8 @@ func (s *Stream) Next() (tree.Statement, error) { } } if err := s.scan.Err(); err != nil { - if err == bufio.ErrTooLong { - err = errors.New("line too long") + if errors.Is(err, bufio.ErrTooLong) { + err = errors.HandledWithMessage(err, "line too long") } return nil, err } diff --git a/pkg/cmd/reduce/main.go b/pkg/cmd/reduce/main.go index 4d04ba6db803..f9256a687977 100644 --- a/pkg/cmd/reduce/main.go +++ b/pkg/cmd/reduce/main.go @@ -29,6 +29,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/testutils/reduce" "github.com/cockroachdb/cockroach/pkg/testutils/reduce/reducesql" + "github.com/cockroachdb/errors" ) var ( @@ -124,7 +125,7 @@ func reduceSQL(path, contains string, workers int, verbose bool) (string, error) out, err := cmd.CombinedOutput() switch err := err.(type) { case *exec.Error: - if err.Err == exec.ErrNotFound { + if errors.Is(err.Err, exec.ErrNotFound) { log.Fatal(err) } case *os.PathError: diff --git a/pkg/cmd/roachprod/cloud/gc.go b/pkg/cmd/roachprod/cloud/gc.go index 06ee4d776e28..8aef8a5ff351 100644 --- a/pkg/cmd/roachprod/cloud/gc.go +++ b/pkg/cmd/roachprod/cloud/gc.go @@ -26,6 +26,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/cmd/roachprod/config" "github.com/cockroachdb/cockroach/pkg/cmd/roachprod/vm" "github.com/cockroachdb/cockroach/pkg/util/timeutil" + "github.com/cockroachdb/errors" "github.com/nlopes/slack" ) @@ -314,7 +315,7 @@ func GCClusters(cloud *Cloud, dryrun bool) error { userChannel, err := findUserChannel(client, user+config.EmailDomain) if err == nil { postStatus(client, userChannel, dryrun, status, nil) - } else if err != errNoSlackClient { + } else if !errors.Is(err, errNoSlackClient) { log.Printf("could not deliver Slack DM to %s: %v", user+config.EmailDomain, err) } } diff --git a/pkg/cmd/roachprod/vm/azure/azure.go b/pkg/cmd/roachprod/vm/azure/azure.go index 459fb1883ab2..5fb1822a86d5 100644 --- a/pkg/cmd/roachprod/vm/azure/azure.go +++ b/pkg/cmd/roachprod/vm/azure/azure.go @@ -412,7 +412,7 @@ func (p *Provider) List() (vm.List, error) { if err != nil { return nil, err } - if err := p.fillNetworkDetails(ctx, &m, nicID); err == vm.ErrBadNetwork { + if err := p.fillNetworkDetails(ctx, &m, nicID); errors.Is(err, vm.ErrBadNetwork) { m.Errors = append(m.Errors, err) } else if err != nil { return nil, err diff --git a/pkg/cmd/roachtest/cluster.go b/pkg/cmd/roachtest/cluster.go index 83eff1b2648e..970fbc4c8eff 100644 --- a/pkg/cmd/roachtest/cluster.go +++ b/pkg/cmd/roachtest/cluster.go @@ -2527,7 +2527,7 @@ func (m *monitor) wait(args ...string) error { cmd.Stdout = io.MultiWriter(pipeW, monL.stdout) cmd.Stderr = monL.stderr if err := cmd.Run(); err != nil { - if err != context.Canceled && !strings.Contains(err.Error(), "killed") { + if !errors.Is(err, context.Canceled) && !strings.Contains(err.Error(), "killed") { // The expected reason for an error is that the monitor was killed due // to the context being canceled. Any other error is an actual error. setMonitorCmdErr(err) diff --git a/pkg/cmd/roachtest/rebalance_load.go b/pkg/cmd/roachtest/rebalance_load.go index 87afdea5d610..860e7669b817 100644 --- a/pkg/cmd/roachtest/rebalance_load.go +++ b/pkg/cmd/roachtest/rebalance_load.go @@ -19,6 +19,7 @@ import ( "time" "github.com/cockroachdb/cockroach/pkg/util/timeutil" + "github.com/cockroachdb/errors" "golang.org/x/sync/errgroup" ) @@ -73,7 +74,7 @@ func registerRebalanceLoad(r *testRegistry) { "./workload run kv --read-percent=95 --tolerate-errors --concurrency=%d "+ "--duration=%v {pgurl:1-%d}", concurrency, maxDuration, len(roachNodes))) - if ctx.Err() == context.Canceled { + if errors.Is(ctx.Err(), context.Canceled) { // We got canceled either because lease balance was achieved or the // other worker hit an error. In either case, it's not this worker's // fault. diff --git a/pkg/cmd/roachvet/main.go b/pkg/cmd/roachvet/main.go index 2d313586137c..b1deb1948e93 100644 --- a/pkg/cmd/roachvet/main.go +++ b/pkg/cmd/roachvet/main.go @@ -15,6 +15,7 @@ package main import ( "github.com/cockroachdb/cockroach/pkg/testutils/lint/passes/descriptormarshal" + "github.com/cockroachdb/cockroach/pkg/testutils/lint/passes/errcmp" "github.com/cockroachdb/cockroach/pkg/testutils/lint/passes/fmtsafe" "github.com/cockroachdb/cockroach/pkg/testutils/lint/passes/hash" "github.com/cockroachdb/cockroach/pkg/testutils/lint/passes/nocopy" @@ -57,6 +58,7 @@ func main() { timer.Analyzer, unconvert.Analyzer, fmtsafe.Analyzer, + errcmp.Analyzer, // Standard go vet analyzers: asmdecl.Analyzer, diff --git a/pkg/gossip/infostore.go b/pkg/gossip/infostore.go index 1bc0d23e0b4b..d1ec956fc459 100644 --- a/pkg/gossip/infostore.go +++ b/pkg/gossip/infostore.go @@ -399,7 +399,7 @@ func (is *infoStore) combine( // the data in *is is newer than in *delta. if addErr := is.addInfo(key, &infoCopy); addErr == nil { freshCount++ - } else if addErr != errNotFresh { + } else if !errors.Is(addErr, errNotFresh) { err = addErr } } diff --git a/pkg/jobs/jobsprotectedts/jobs_protected_ts_test.go b/pkg/jobs/jobsprotectedts/jobs_protected_ts_test.go index e14c6b8c0da8..5f70afaef653 100644 --- a/pkg/jobs/jobsprotectedts/jobs_protected_ts_test.go +++ b/pkg/jobs/jobsprotectedts/jobs_protected_ts_test.go @@ -32,6 +32,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/testutils/testcluster" "github.com/cockroachdb/cockroach/pkg/util/leaktest" "github.com/cockroachdb/cockroach/pkg/util/uuid" + "github.com/cockroachdb/errors" "github.com/stretchr/testify/require" ) @@ -90,7 +91,7 @@ func TestJobsProtectedTimestamp(t *testing.T) { _, recRemains := mkJobAndRecord() ensureNotExists := func(ctx context.Context, txn *kv.Txn, ptsID uuid.UUID) (err error) { _, err = ptp.GetRecord(ctx, txn, ptsID) - if err == protectedts.ErrNotExists { + if errors.Is(err, protectedts.ErrNotExists) { return nil } return fmt.Errorf("waiting for %v, got %v", protectedts.ErrNotExists, err) diff --git a/pkg/kv/kvclient/kvcoord/range_cache_test.go b/pkg/kv/kvclient/kvcoord/range_cache_test.go index 6b004ed51f34..bbf9449bf8d0 100644 --- a/pkg/kv/kvclient/kvcoord/range_cache_test.go +++ b/pkg/kv/kvclient/kvcoord/range_cache_test.go @@ -493,7 +493,7 @@ func TestRangeCacheContextCancellation(t *testing.T) { } expectContextCancellation := func(t *testing.T, c <-chan error) { - if err := <-c; errors.Cause(err) != context.Canceled { + if err := <-c; !errors.Is(err, context.Canceled) { t.Errorf("expected context cancellation error, found %v", err) } } diff --git a/pkg/kv/kvclient/kvcoord/txn_coord_sender_savepoints.go b/pkg/kv/kvclient/kvcoord/txn_coord_sender_savepoints.go index 2da73800b31a..0c787b406122 100644 --- a/pkg/kv/kvclient/kvcoord/txn_coord_sender_savepoints.go +++ b/pkg/kv/kvclient/kvcoord/txn_coord_sender_savepoints.go @@ -122,7 +122,7 @@ func (tc *TxnCoordSender) RollbackToSavepoint(ctx context.Context, s kv.Savepoin sp := s.(*savepoint) err := tc.checkSavepointLocked(sp) if err != nil { - if err == errSavepointInvalidAfterTxnRestart { + if errors.Is(err, errSavepointInvalidAfterTxnRestart) { err = roachpb.NewTransactionRetryWithProtoRefreshError( "cannot rollback to savepoint after a transaction restart", tc.mu.txn.ID, @@ -169,7 +169,7 @@ func (tc *TxnCoordSender) ReleaseSavepoint(ctx context.Context, s kv.SavepointTo sp := s.(*savepoint) err := tc.checkSavepointLocked(sp) - if err == errSavepointInvalidAfterTxnRestart { + if errors.Is(err, errSavepointInvalidAfterTxnRestart) { err = roachpb.NewTransactionRetryWithProtoRefreshError( "cannot release savepoint after a transaction restart", tc.mu.txn.ID, diff --git a/pkg/kv/kvserver/client_raft_test.go b/pkg/kv/kvserver/client_raft_test.go index c23a1adc829f..1565d30a40fc 100644 --- a/pkg/kv/kvserver/client_raft_test.go +++ b/pkg/kv/kvserver/client_raft_test.go @@ -1066,7 +1066,7 @@ func TestFailedSnapshotFillsReservation(t *testing.T) { // "snapshot accepted" message. expectedErr := errors.Errorf("") stream := fakeSnapshotStream{nil, expectedErr} - if err := mtc.stores[1].HandleSnapshot(&header, stream); err != expectedErr { + if err := mtc.stores[1].HandleSnapshot(&header, stream); !errors.Is(err, expectedErr) { t.Fatalf("expected error %s, but found %v", expectedErr, err) } if n := mtc.stores[1].ReservationCount(); n != 0 { diff --git a/pkg/kv/kvserver/client_test.go b/pkg/kv/kvserver/client_test.go index 9b2a203e2a32..917de2b844fc 100644 --- a/pkg/kv/kvserver/client_test.go +++ b/pkg/kv/kvserver/client_test.go @@ -1399,7 +1399,7 @@ func (m *multiTestContext) heartbeatLiveness(ctx context.Context, store int) err } for r := retry.StartWithCtx(ctx, retry.Options{MaxRetries: 5}); r.Next(); { - if err = nl.Heartbeat(ctx, l); err != kvserver.ErrEpochIncremented { + if err = nl.Heartbeat(ctx, l); !errors.Is(err, kvserver.ErrEpochIncremented) { break } } diff --git a/pkg/kv/kvserver/concurrency/lock_table_waiter.go b/pkg/kv/kvserver/concurrency/lock_table_waiter.go index 1942cd9abad9..a3a9fe33f3bf 100644 --- a/pkg/kv/kvserver/concurrency/lock_table_waiter.go +++ b/pkg/kv/kvserver/concurrency/lock_table_waiter.go @@ -24,6 +24,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/stop" "github.com/cockroachdb/cockroach/pkg/util/timeutil" + "github.com/cockroachdb/errors" ) // LockTableLivenessPushDelay sets the delay before pushing in order to detect @@ -278,7 +279,7 @@ func (w *lockTableWaiterImpl) WaitOn( pushCtx, pushCancel := context.WithCancel(ctx) go w.watchForNotifications(pushCtx, pushCancel, newStateC) err = w.pushRequestTxn(pushCtx, req, timerWaitingState) - if pushCtx.Err() == context.Canceled { + if errors.Is(pushCtx.Err(), context.Canceled) { // Ignore the context canceled error. If this was for the // parent context then we'll notice on the next select. err = nil diff --git a/pkg/kv/kvserver/gc_queue.go b/pkg/kv/kvserver/gc_queue.go index 987d65b4521a..4b53de87f0c9 100644 --- a/pkg/kv/kvserver/gc_queue.go +++ b/pkg/kv/kvserver/gc_queue.go @@ -472,7 +472,7 @@ func (gcq *gcQueue) process(ctx context.Context, repl *Replica, sysCfg *config.S gcq.store.metrics.GCResolveSuccess.Inc(int64(len(intents))) } }) - if errors.Cause(err) == stop.ErrThrottled { + if errors.Is(err, stop.ErrThrottled) { log.Eventf(ctx, "processing txn %s: %s; skipping for future GC", txn.ID.Short(), err) return nil } diff --git a/pkg/kv/kvserver/idalloc/id_alloc_test.go b/pkg/kv/kvserver/idalloc/id_alloc_test.go index 760a33b249ef..2678f66a2e81 100644 --- a/pkg/kv/kvserver/idalloc/id_alloc_test.go +++ b/pkg/kv/kvserver/idalloc/id_alloc_test.go @@ -184,7 +184,7 @@ func TestAllocateErrorAndRecovery(t *testing.T) { defer cancel() for i := 0; i < routines; i++ { id, err := idAlloc.Allocate(ctx) - if id != 0 || err != context.DeadlineExceeded { + if id != 0 || !errors.Is(err, context.DeadlineExceeded) { t.Fatalf("expected context cancellation, found id=%d, err=%v", id, err) } } diff --git a/pkg/kv/kvserver/intentresolver/intent_resolver.go b/pkg/kv/kvserver/intentresolver/intent_resolver.go index c07aa369f4ec..e74bdce2bdb2 100644 --- a/pkg/kv/kvserver/intentresolver/intent_resolver.go +++ b/pkg/kv/kvserver/intentresolver/intent_resolver.go @@ -405,7 +405,7 @@ func (ir *IntentResolver) runAsyncTask( taskFn, ) if err != nil { - if err == stop.ErrThrottled { + if errors.Is(err, stop.ErrThrottled) { ir.Metrics.IntentResolverAsyncThrottled.Inc(1) if allowSyncProcessing { // A limited task was not available. Rather than waiting for diff --git a/pkg/kv/kvserver/intentresolver/intent_resolver_test.go b/pkg/kv/kvserver/intentresolver/intent_resolver_test.go index 07498770b383..80e0cc5a4dea 100644 --- a/pkg/kv/kvserver/intentresolver/intent_resolver_test.go +++ b/pkg/kv/kvserver/intentresolver/intent_resolver_test.go @@ -279,7 +279,7 @@ func TestCleanupIntentsAsyncThrottled(t *testing.T) { // Running with allowSyncProcessing = false should result in an error and no // requests being sent. err := ir.CleanupIntentsAsync(context.Background(), testIntents, false) - assert.Equal(t, errors.Cause(err), stop.ErrThrottled) + assert.True(t, errors.Is(err, stop.ErrThrottled)) // Running with allowSyncProcessing = true should result in the synchronous // processing of the intents resulting in no error and the consumption of the // sendFuncs. diff --git a/pkg/kv/kvserver/node_liveness.go b/pkg/kv/kvserver/node_liveness.go index 969d275acac6..c937c73d0857 100644 --- a/pkg/kv/kvserver/node_liveness.go +++ b/pkg/kv/kvserver/node_liveness.go @@ -235,7 +235,7 @@ func (nl *NodeLiveness) SetDraining(ctx context.Context, drain bool, reporter fu ctx = nl.ambientCtx.AnnotateCtx(ctx) for r := retry.StartWithCtx(ctx, base.DefaultRetryOptions()); r.Next(); { liveness, err := nl.Self() - if err != nil && err != ErrNoLivenessRecord { + if err != nil && !errors.Is(err, ErrNoLivenessRecord) { log.Errorf(ctx, "unexpected error getting liveness: %+v", err) } err = nl.setDrainingInternal(ctx, liveness, drain, reporter) @@ -318,7 +318,7 @@ func (nl *NodeLiveness) SetDecommissioning( for { changeCommitted, err := attempt() - if errors.Cause(err) == errChangeDecommissioningFailed { + if errors.Is(err, errChangeDecommissioningFailed) { continue // expected when epoch incremented } return changeCommitted, err @@ -366,7 +366,7 @@ func (nl *NodeLiveness) setDrainingInternal( if log.V(1) { log.Infof(ctx, "updating liveness record: %v", err) } - if err == errNodeDrainingSet { + if errors.Is(err, errNodeDrainingSet) { return nil } return err @@ -478,11 +478,11 @@ func (nl *NodeLiveness) StartHeartbeat( // Retry heartbeat in the event the conditional put fails. for r := retry.StartWithCtx(ctx, retryOpts); r.Next(); { liveness, err := nl.Self() - if err != nil && err != ErrNoLivenessRecord { + if err != nil && !errors.Is(err, ErrNoLivenessRecord) { log.Errorf(ctx, "unexpected error getting liveness: %+v", err) } if err := nl.heartbeatInternal(ctx, liveness, incrementEpoch); err != nil { - if err == ErrEpochIncremented { + if errors.Is(err, ErrEpochIncremented) { log.Infof(ctx, "%s; retrying", err) continue } @@ -632,7 +632,7 @@ func (nl *NodeLiveness) heartbeatInternal( // Otherwise, return error. return ErrEpochIncremented }); err != nil { - if err == errNodeAlreadyLive { + if errors.Is(err, errNodeAlreadyLive) { nl.metrics.HeartbeatSuccesses.Inc(1) return nil } @@ -848,7 +848,7 @@ func (nl *NodeLiveness) updateLivenessAttempt( // put failures. if !update.ignoreCache { l, err := nl.GetLiveness(update.NodeID) - if err != nil && err != ErrNoLivenessRecord { + if err != nil && !errors.Is(err, ErrNoLivenessRecord) { return err } if err == nil && l != oldLiveness { @@ -994,7 +994,7 @@ func (nl *NodeLiveness) numLiveNodes() int64 { defer nl.mu.RUnlock() self, err := nl.getLivenessLocked(selfID) - if err == ErrNoLivenessRecord { + if errors.Is(err, ErrNoLivenessRecord) { return 0 } if err != nil { diff --git a/pkg/kv/kvserver/node_liveness_test.go b/pkg/kv/kvserver/node_liveness_test.go index c781f0e1affa..bf016fbf7509 100644 --- a/pkg/kv/kvserver/node_liveness_test.go +++ b/pkg/kv/kvserver/node_liveness_test.go @@ -108,7 +108,7 @@ func TestNodeLiveness(t *testing.T) { if err == nil { break } - if err == kvserver.ErrEpochIncremented { + if errors.Is(err, kvserver.ErrEpochIncremented) { log.Warningf(context.Background(), "retrying after %s", err) continue } @@ -316,7 +316,7 @@ func TestNodeLivenessEpochIncrement(t *testing.T) { } // Verify error on incrementing an already-incremented epoch. - if err := mtc.nodeLivenesses[0].IncrementEpoch(context.Background(), oldLiveness); err != kvserver.ErrEpochAlreadyIncremented { + if err := mtc.nodeLivenesses[0].IncrementEpoch(context.Background(), oldLiveness); !errors.Is(err, kvserver.ErrEpochAlreadyIncremented) { t.Fatalf("unexpected error incrementing a non-live node: %+v", err) } @@ -475,7 +475,7 @@ func TestNodeLivenessGetIsLiveMap(t *testing.T) { testutils.SucceedsSoon(t, func() error { if err := mtc.nodeLivenesses[0].Heartbeat(context.Background(), liveness); err != nil { - if err == kvserver.ErrEpochIncremented { + if errors.Is(err, kvserver.ErrEpochIncremented) { return err } t.Fatal(err) @@ -609,7 +609,7 @@ func TestNodeLivenessConcurrentIncrementEpochs(t *testing.T) { }() } for i := 0; i < concurrency; i++ { - if err := <-errCh; err != nil && err != kvserver.ErrEpochAlreadyIncremented { + if err := <-errCh; err != nil && !errors.Is(err, kvserver.ErrEpochAlreadyIncremented) { t.Fatalf("concurrent increment epoch %d failed: %+v", i, err) } } @@ -977,7 +977,7 @@ func TestNodeLivenessDecommissionAbsent(t *testing.T) { // When the node simply never existed, expect an error. if _, err := mtc.nodeLivenesses[0].SetDecommissioning( ctx, goneNodeID, true, - ); errors.Cause(err) != kvserver.ErrNoLivenessRecord { + ); !errors.Is(err, kvserver.ErrNoLivenessRecord) { t.Fatal(err) } diff --git a/pkg/kv/kvserver/protectedts/ptreconcile/reconciler.go b/pkg/kv/kvserver/protectedts/ptreconcile/reconciler.go index 4abb948511d6..14661ee9c820 100644 --- a/pkg/kv/kvserver/protectedts/ptreconcile/reconciler.go +++ b/pkg/kv/kvserver/protectedts/ptreconcile/reconciler.go @@ -28,6 +28,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/stop" "github.com/cockroachdb/cockroach/pkg/util/timeutil" + "github.com/cockroachdb/errors" ) // ReconcileInterval is the interval between two generations of the reports. @@ -167,7 +168,7 @@ func (r *Reconciler) reconcile(ctx context.Context) { return nil } err = r.pts.Release(ctx, txn, rec.ID) - if err != nil && err != protectedts.ErrNotExists { + if err != nil && !errors.Is(err, protectedts.ErrNotExists) { return err } didRemove = true diff --git a/pkg/kv/kvserver/queue.go b/pkg/kv/kvserver/queue.go index 93d8e050f764..cc97c4aaebe4 100644 --- a/pkg/kv/kvserver/queue.go +++ b/pkg/kv/kvserver/queue.go @@ -202,8 +202,7 @@ var ( ) func isExpectedQueueError(err error) bool { - cause := errors.Cause(err) - return err == nil || cause == errQueueDisabled + return err == nil || errors.Is(err, errQueueDisabled) } // shouldQueueAgain is a helper function to determine whether the diff --git a/pkg/kv/kvserver/queue_test.go b/pkg/kv/kvserver/queue_test.go index a8ab00197755..8fc4d6ba2b7b 100644 --- a/pkg/kv/kvserver/queue_test.go +++ b/pkg/kv/kvserver/queue_test.go @@ -1061,7 +1061,7 @@ func TestBaseQueueDisable(t *testing.T) { } // Add the range directly, bypassing shouldQueue. - if _, err := bq.testingAdd(ctx, r, 1.0); err != errQueueDisabled { + if _, err := bq.testingAdd(ctx, r, 1.0); !errors.Is(err, errQueueDisabled) { t.Fatal(err) } diff --git a/pkg/kv/kvserver/raft_log_queue_test.go b/pkg/kv/kvserver/raft_log_queue_test.go index eca1228c6edd..770909f903c5 100644 --- a/pkg/kv/kvserver/raft_log_queue_test.go +++ b/pkg/kv/kvserver/raft_log_queue_test.go @@ -744,7 +744,7 @@ func TestTruncateLog(t *testing.T) { tc.repl.mu.Lock() _, err = tc.repl.raftEntriesLocked(indexes[4], indexes[9], math.MaxUint64) tc.repl.mu.Unlock() - if err != raft.ErrCompacted { + if !errors.Is(err, raft.ErrCompacted) { t.Errorf("expected ErrCompacted, got %s", err) } @@ -763,7 +763,7 @@ func TestTruncateLog(t *testing.T) { tc.repl.mu.Lock() _, err = tc.repl.raftTermRLocked(indexes[3]) tc.repl.mu.Unlock() - if err != raft.ErrCompacted { + if !errors.Is(err, raft.ErrCompacted) { t.Errorf("expected ErrCompacted, got %s", err) } diff --git a/pkg/kv/kvserver/replica.go b/pkg/kv/kvserver/replica.go index fd1477249d12..a7b0c5b60d9c 100644 --- a/pkg/kv/kvserver/replica.go +++ b/pkg/kv/kvserver/replica.go @@ -1444,7 +1444,7 @@ func (r *Replica) maybeWatchForMerge(ctx context.Context) error { r.mu.Unlock() r.raftMu.Unlock() }) - if err == stop.ErrUnavailable { + if errors.Is(err, stop.ErrUnavailable) { // We weren't able to launch a goroutine to watch for the merge's completion // because the server is shutting down. Normally failing to launch the // watcher goroutine would wedge pending requests on the replica's diff --git a/pkg/kv/kvserver/replica_command.go b/pkg/kv/kvserver/replica_command.go index 3fb3e1494940..58d5941d3f20 100644 --- a/pkg/kv/kvserver/replica_command.go +++ b/pkg/kv/kvserver/replica_command.go @@ -1877,7 +1877,7 @@ func (r *Replica) sendSnapshot( r.store.Engine().NewBatch, sent, ); err != nil { - if errors.Cause(err) == errMalformedSnapshot { + if errors.Is(err, errMalformedSnapshot) { tag := fmt.Sprintf("r%d_%s", r.RangeID, snap.SnapUUID.Short()) if dir, err := r.store.checkpoint(ctx, tag); err != nil { log.Warningf(ctx, "unable to create checkpoint %s: %+v", dir, err) diff --git a/pkg/kv/kvserver/replica_gossip.go b/pkg/kv/kvserver/replica_gossip.go index 1529a997ac68..a33f7ae77988 100644 --- a/pkg/kv/kvserver/replica_gossip.go +++ b/pkg/kv/kvserver/replica_gossip.go @@ -93,7 +93,7 @@ func (r *Replica) MaybeGossipSystemConfig(ctx context.Context) error { // TODO(marc): check for bad split in the middle of the SystemConfig span. loadedCfg, err := r.loadSystemConfig(ctx) if err != nil { - if err == errSystemConfigIntent { + if errors.Is(err, errSystemConfigIntent) { log.VEventf(ctx, 2, "not gossiping system config because intents were found on SystemConfigSpan") r.markSystemConfigGossipFailed() return nil diff --git a/pkg/kv/kvserver/replica_init.go b/pkg/kv/kvserver/replica_init.go index 9619f1f043ed..7ddbfc9afb49 100644 --- a/pkg/kv/kvserver/replica_init.go +++ b/pkg/kv/kvserver/replica_init.go @@ -249,7 +249,7 @@ func (r *Replica) maybeInitializeRaftGroup(ctx context.Context) { // the below withRaftGroupLocked will no-op. if err := r.withRaftGroupLocked(true, func(raftGroup *raft.RawNode) (bool, error) { return true, nil - }); err != nil && err != errRemoved { + }); err != nil && !errors.Is(err, errRemoved) { log.VErrEventf(ctx, 1, "unable to initialize raft group: %s", err) } } diff --git a/pkg/kv/kvserver/replica_proposal_buf.go b/pkg/kv/kvserver/replica_proposal_buf.go index 15b3fd0e1e75..ede0729c0dac 100644 --- a/pkg/kv/kvserver/replica_proposal_buf.go +++ b/pkg/kv/kvserver/replica_proposal_buf.go @@ -18,6 +18,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/protoutil" + "github.com/cockroachdb/errors" "go.etcd.io/etcd/raft" "go.etcd.io/etcd/raft/raftpb" ) @@ -460,7 +461,7 @@ func (b *propBuf) FlushLockedWithRaftGroup(raftGroup *raft.RawNode) (int, error) if err := raftGroup.ProposeConfChange( cc, - ); err != nil && err != raft.ErrProposalDropped { + ); err != nil && !errors.Is(err, raft.ErrProposalDropped) { // Silently ignore dropped proposals (they were always silently // ignored prior to the introduction of ErrProposalDropped). // TODO(bdarnell): Handle ErrProposalDropped better. @@ -503,7 +504,7 @@ func proposeBatch(raftGroup *raft.RawNode, replID roachpb.ReplicaID, ents []raft Type: raftpb.MsgProp, From: uint64(replID), Entries: ents, - }); err == raft.ErrProposalDropped { + }); errors.Is(err, raft.ErrProposalDropped) { // Silently ignore dropped proposals (they were always silently // ignored prior to the introduction of ErrProposalDropped). // TODO(bdarnell): Handle ErrProposalDropped better. diff --git a/pkg/kv/kvserver/replica_proposal_buf_test.go b/pkg/kv/kvserver/replica_proposal_buf_test.go index 2f81e2556207..b09afbe71440 100644 --- a/pkg/kv/kvserver/replica_proposal_buf_test.go +++ b/pkg/kv/kvserver/replica_proposal_buf_test.go @@ -180,7 +180,7 @@ func TestProposalBufferConcurrentWithDestroy(t *testing.T) { pd, data := newPropData(false) mlai, err := b.Insert(pd, data) if err != nil { - if err == dsErr { + if errors.Is(err, dsErr) { return nil } return errors.Wrap(err, "Insert") diff --git a/pkg/kv/kvserver/replica_raft.go b/pkg/kv/kvserver/replica_raft.go index 8da15f5b8219..f259dcf6025e 100644 --- a/pkg/kv/kvserver/replica_raft.go +++ b/pkg/kv/kvserver/replica_raft.go @@ -387,7 +387,7 @@ func (r *Replica) stepRaftGroup(req *RaftMessageRequest) error { r.unquiesceWithOptionsLocked(false /* campaignOnWake */) r.mu.lastUpdateTimes.update(req.FromReplica.ReplicaID, timeutil.Now()) err := raftGroup.Step(req.Message) - if err == raft.ErrProposalDropped { + if errors.Is(err, raft.ErrProposalDropped) { // A proposal was forwarded to this replica but we couldn't propose it. // Swallow the error since we don't have an effective way of signaling // this to the sender. @@ -467,7 +467,7 @@ func (r *Replica) handleRaftReadyRaftMuLocked( return unquiesceAndWakeLeader, nil }) r.mu.Unlock() - if err == errRemoved { + if errors.Is(err, errRemoved) { // If we've been removed then just return. return stats, "", nil } else if err != nil { @@ -1193,7 +1193,7 @@ func (r *Replica) sendRaftMessage(ctx context.Context, msg raftpb.Message) { r.mu.droppedMessages++ raftGroup.ReportUnreachable(msg.To) return true, nil - }); err != nil && err != errRemoved { + }); err != nil && !errors.Is(err, errRemoved) { log.Fatalf(ctx, "%v", err) } } @@ -1236,7 +1236,7 @@ func (r *Replica) reportSnapshotStatus(ctx context.Context, to roachpb.ReplicaID if err := r.withRaftGroup(true, func(raftGroup *raft.RawNode) (bool, error) { raftGroup.ReportSnapshot(uint64(to), snapStatus) return true, nil - }); err != nil && err != errRemoved { + }); err != nil && !errors.Is(err, errRemoved) { log.Fatalf(ctx, "%v", err) } } diff --git a/pkg/kv/kvserver/replica_raftstorage.go b/pkg/kv/kvserver/replica_raftstorage.go index b37364242429..3375bf3c90b7 100644 --- a/pkg/kv/kvserver/replica_raftstorage.go +++ b/pkg/kv/kvserver/replica_raftstorage.go @@ -272,7 +272,7 @@ func term( // entries() accepts a `nil` sideloaded storage and will skip inlining of // sideloaded entries. We only need the term, so this is what we do. ents, err := entries(ctx, rsl, reader, rangeID, eCache, nil /* sideloaded */, i, i+1, math.MaxUint64 /* maxBytes */) - if err == raft.ErrCompacted { + if errors.Is(err, raft.ErrCompacted) { ts, _, err := rsl.LoadRaftTruncatedState(ctx, reader) if err != nil { return 0, err diff --git a/pkg/kv/kvserver/replica_range_lease.go b/pkg/kv/kvserver/replica_range_lease.go index 4caf3f023f3b..681b1babc661 100644 --- a/pkg/kv/kvserver/replica_range_lease.go +++ b/pkg/kv/kvserver/replica_range_lease.go @@ -379,7 +379,7 @@ func (p *pendingLeaseRequest) requestLeaseAsync( // so we don't log it as an error. // // https://github.com/cockroachdb/cockroach/issues/35986 - if err != ErrEpochAlreadyIncremented { + if !errors.Is(err, ErrEpochAlreadyIncremented) { log.Errorf(ctx, "%v", err) } } diff --git a/pkg/kv/kvserver/replica_sideload.go b/pkg/kv/kvserver/replica_sideload.go index 9f07dcb01309..c4d444a5608c 100644 --- a/pkg/kv/kvserver/replica_sideload.go +++ b/pkg/kv/kvserver/replica_sideload.go @@ -232,7 +232,7 @@ func maybePurgeSideloaded( var totalSize int64 for i := firstIndex; i <= lastIndex; i++ { size, err := ss.Purge(ctx, i, term) - if err != nil && errors.Cause(err) != errSideloadedFileNotFound { + if err != nil && !errors.Is(err, errSideloadedFileNotFound) { return totalSize, err } totalSize += size diff --git a/pkg/kv/kvserver/replica_sideload_test.go b/pkg/kv/kvserver/replica_sideload_test.go index 47652732bc3c..a144c0388a0b 100644 --- a/pkg/kv/kvserver/replica_sideload_test.go +++ b/pkg/kv/kvserver/replica_sideload_test.go @@ -200,7 +200,7 @@ func testSideloadingSideloadedStorage( }, }, } { - if err := test.fun(); err != test.err { + if err := test.fun(); !errors.Is(err, test.err) { t.Fatalf("%d: expected %v, got %v", n, test.err, err) } if err := ss.Clear(ctx); err != nil { @@ -266,7 +266,7 @@ func testSideloadingSideloadedStorage( } // Indexes below are gone. for _, i := range payloads[:n] { - if _, err := ss.Get(ctx, i, term); err != errSideloadedFileNotFound { + if _, err := ss.Get(ctx, i, term); !errors.Is(err, errSideloadedFileNotFound) { t.Fatalf("%d.%d: %+v", n, i, err) } } diff --git a/pkg/kv/kvserver/replica_test.go b/pkg/kv/kvserver/replica_test.go index 0f96d3cbe85b..ba1979913bd9 100644 --- a/pkg/kv/kvserver/replica_test.go +++ b/pkg/kv/kvserver/replica_test.go @@ -6817,7 +6817,7 @@ func TestReplicaLoadSystemConfigSpanIntent(t *testing.T) { } // Verify that the intent trips up loading the SystemConfig data. - if _, err := repl.loadSystemConfig(context.Background()); err != errSystemConfigIntent { + if _, err := repl.loadSystemConfig(context.Background()); !errors.Is(err, errSystemConfigIntent) { t.Fatal(err) } @@ -7099,7 +7099,7 @@ func TestEntries(t *testing.T) { if tc.expError == nil && err != nil { t.Errorf("%d: expected no error, got %s", i, err) continue - } else if err != tc.expError { + } else if !errors.Is(err, tc.expError) { t.Errorf("%d: expected error %s, got %s", i, tc.expError, err) continue } @@ -7166,10 +7166,10 @@ func TestTerm(t *testing.T) { } // Truncated logs should return an ErrCompacted error. - if _, err := tc.repl.raftTermRLocked(indexes[1]); err != raft.ErrCompacted { + if _, err := tc.repl.raftTermRLocked(indexes[1]); !errors.Is(err, raft.ErrCompacted) { t.Errorf("expected ErrCompacted, got %s", err) } - if _, err := tc.repl.raftTermRLocked(indexes[3]); err != raft.ErrCompacted { + if _, err := tc.repl.raftTermRLocked(indexes[3]); !errors.Is(err, raft.ErrCompacted) { t.Errorf("expected ErrCompacted, got %s", err) } @@ -7198,10 +7198,10 @@ func TestTerm(t *testing.T) { } // Terms for after the last index should return ErrUnavailable. - if _, err := tc.repl.raftTermRLocked(lastIndex + 1); err != raft.ErrUnavailable { + if _, err := tc.repl.raftTermRLocked(lastIndex + 1); !errors.Is(err, raft.ErrUnavailable) { t.Errorf("expected ErrUnavailable, got %s", err) } - if _, err := tc.repl.raftTermRLocked(indexes[9] + 1000); err != raft.ErrUnavailable { + if _, err := tc.repl.raftTermRLocked(indexes[9] + 1000); !errors.Is(err, raft.ErrUnavailable) { t.Errorf("expected ErrUnavailable, got %s", err) } } diff --git a/pkg/kv/kvserver/store.go b/pkg/kv/kvserver/store.go index d555e963f3b0..1412ef0f3bb9 100644 --- a/pkg/kv/kvserver/store.go +++ b/pkg/kv/kvserver/store.go @@ -1625,7 +1625,7 @@ func (s *Store) startGossip() { annotatedCtx := repl.AnnotateCtx(ctx) if err := gossipFn.fn(annotatedCtx, repl); err != nil { log.Warningf(annotatedCtx, "could not gossip %s: %+v", gossipFn.description, err) - if err != errPeriodicGossipsDisabled { + if !errors.Is(err, errPeriodicGossipsDisabled) { continue } } diff --git a/pkg/kv/kvserver/store_create_replica.go b/pkg/kv/kvserver/store_create_replica.go index d4d2e15b5760..a46895cdc9c6 100644 --- a/pkg/kv/kvserver/store_create_replica.go +++ b/pkg/kv/kvserver/store_create_replica.go @@ -59,7 +59,7 @@ func (s *Store) getOrCreateReplica( creatingReplica, isLearner, ) - if err == errRetry { + if errors.Is(err, errRetry) { continue } if err != nil { diff --git a/pkg/kv/kvserver/store_snapshot.go b/pkg/kv/kvserver/store_snapshot.go index 620a3051f7a6..2d5a7b09b912 100644 --- a/pkg/kv/kvserver/store_snapshot.go +++ b/pkg/kv/kvserver/store_snapshot.go @@ -429,7 +429,7 @@ func (kvSS *kvBatchSnapshotStrategy) Send( } return nil }); err != nil { - if errors.Cause(err) == errSideloadedFileNotFound { + if errors.Is(err, errSideloadedFileNotFound) { // We're creating the Raft snapshot based on a snapshot of // the engine, but the Raft log may since have been // truncated and corresponding on-disk sideloaded payloads diff --git a/pkg/kv/kvserver/store_test.go b/pkg/kv/kvserver/store_test.go index c89263b7a68a..a71467454202 100644 --- a/pkg/kv/kvserver/store_test.go +++ b/pkg/kv/kvserver/store_test.go @@ -714,7 +714,7 @@ func TestStoreRemoveReplicaDestroy(t *testing.T) { } st := &storagepb.LeaseStatus{Timestamp: repl1.Clock().Now()} - if err = repl1.checkExecutionCanProceed(&roachpb.BatchRequest{}, nil /* g */, st); err != expErr { + if err = repl1.checkExecutionCanProceed(&roachpb.BatchRequest{}, nil /* g */, st); !errors.Is(err, expErr) { t.Fatalf("expected error %s, but got %v", expErr, err) } } @@ -2941,7 +2941,7 @@ func TestSendSnapshotThrottling(t *testing.T) { if sp.failedThrottles != 1 { t.Fatalf("expected 1 failed throttle, but found %d", sp.failedThrottles) } - if err != expectedErr { + if !errors.Is(err, expectedErr) { t.Fatalf("expected error %s, but found %s", err, expectedErr) } } diff --git a/pkg/kv/kvserver/stores_test.go b/pkg/kv/kvserver/stores_test.go index ed18d7d80703..04de1056b19d 100644 --- a/pkg/kv/kvserver/stores_test.go +++ b/pkg/kv/kvserver/stores_test.go @@ -103,7 +103,7 @@ func TestStoresVisitStores(t *testing.T) { errBoom := errors.New("boom") if err := ls.VisitStores(func(s *Store) error { return errBoom - }); err != errBoom { + }); !errors.Is(err, errBoom) { t.Errorf("got unexpected error %v", err) } } diff --git a/pkg/kv/kvserver/tscache/interval_skl.go b/pkg/kv/kvserver/tscache/interval_skl.go index 3a01a913c1c9..cb61cebc869a 100644 --- a/pkg/kv/kvserver/tscache/interval_skl.go +++ b/pkg/kv/kvserver/tscache/interval_skl.go @@ -27,6 +27,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/syncutil" "github.com/cockroachdb/cockroach/pkg/util/uuid" + "github.com/cockroachdb/errors" ) // rangeOptions are passed to AddRange to indicate the bounds of the range. By @@ -309,7 +310,7 @@ func (s *intervalSkl) addRange(from, to []byte, opt rangeOptions, val cacheValue err = fp.addNode(&it, to, val, 0, true /* mustInit */) } - if err == arenaskl.ErrArenaFull { + if errors.Is(err, arenaskl.ErrArenaFull) { return fp } } @@ -327,7 +328,7 @@ func (s *intervalSkl) addRange(from, to []byte, opt rangeOptions, val cacheValue err = fp.addNode(&it, from, val, hasGap, false /* mustInit */) } - if err == arenaskl.ErrArenaFull { + if errors.Is(err, arenaskl.ErrArenaFull) { return fp } @@ -1030,7 +1031,7 @@ func (p *sklPage) scanTo( // Decode the current node's value set. keyVal, gapVal := decodeValueSet(it.Value(), it.Meta()) - if ratchetErr == arenaskl.ErrArenaFull { + if errors.Is(ratchetErr, arenaskl.ErrArenaFull) { // If we failed to ratchet an uninitialized node above, the desired // ratcheting won't be reflected in the decoded values. Perform the // ratcheting manually. diff --git a/pkg/rpc/clock_offset.go b/pkg/rpc/clock_offset.go index da6bc66e832d..cbbcb586db6f 100644 --- a/pkg/rpc/clock_offset.go +++ b/pkg/rpc/clock_offset.go @@ -216,11 +216,11 @@ func (r *RemoteClockMonitor) VerifyClockOffset(ctx context.Context) error { r.mu.Unlock() mean, err := offsets.Mean() - if err != nil && err != stats.EmptyInput { + if err != nil && !errors.Is(err, stats.EmptyInput) { return err } stdDev, err := offsets.StandardDeviation() - if err != nil && err != stats.EmptyInput { + if err != nil && !errors.Is(err, stats.EmptyInput) { return err } r.metrics.ClockOffsetMeanNanos.Update(int64(mean)) diff --git a/pkg/rpc/context_test.go b/pkg/rpc/context_test.go index e7a1f0ece070..abbc59e1d52c 100644 --- a/pkg/rpc/context_test.go +++ b/pkg/rpc/context_test.go @@ -288,7 +288,7 @@ func TestHeartbeatHealth(t *testing.T) { // Wait for the connection. testutils.SucceedsSoon(t, func() error { err := clientCtx.TestingConnHealth(remoteAddr, serverNodeID) - if err != nil && err != ErrNotHeartbeated { + if err != nil && !errors.Is(err, ErrNotHeartbeated) { t.Fatal(err) } return err @@ -343,7 +343,7 @@ func TestHeartbeatHealth(t *testing.T) { if err != nil { t.Fatal(err) } - if err := clientCtx.TestingConnHealth(lisNonExistentConnection.Addr().String(), 3); err != ErrNotHeartbeated { + if err := clientCtx.TestingConnHealth(lisNonExistentConnection.Addr().String(), 3); !errors.Is(err, ErrNotHeartbeated) { t.Errorf("wanted ErrNotHeartbeated, not %v", err) } // The connection to Node 3 on the lisNonExistentConnection should be @@ -353,7 +353,7 @@ func TestHeartbeatHealth(t *testing.T) { 1 /* initializing */, 1 /* nominal */, 0 /* failed */) }) - if err := clientCtx.TestingConnHealth(clientCtx.Addr, clientNodeID); err != ErrNotHeartbeated { + if err := clientCtx.TestingConnHealth(clientCtx.Addr, clientNodeID); !errors.Is(err, ErrNotHeartbeated) { t.Errorf("wanted ErrNotHeartbeated, not %v", err) } @@ -362,7 +362,7 @@ func TestHeartbeatHealth(t *testing.T) { // an internal server has been registered. clientCtx.SetLocalInternalServer(&internalServer{}) - if err := clientCtx.TestingConnHealth(clientCtx.Addr, clientNodeID); err != ErrNotHeartbeated { + if err := clientCtx.TestingConnHealth(clientCtx.Addr, clientNodeID); !errors.Is(err, ErrNotHeartbeated) { t.Errorf("wanted ErrNotHeartbeated, not %v", err) } if err := clientCtx.TestingConnHealth(clientCtx.AdvertiseAddr, clientNodeID); err != nil { @@ -559,7 +559,7 @@ func TestHeartbeatHealthTransport(t *testing.T) { // ErrNotHeartbeated, but there are brief periods during which we // could get one of the grpc errors below (while the old // connection is in the middle of closing). - if err == ErrNotHeartbeated { + if errors.Is(err, ErrNotHeartbeated) { return true } // The expected code here is Unavailable, but at least on OSX you can also get diff --git a/pkg/rpc/nodedialer/nodedialer_test.go b/pkg/rpc/nodedialer/nodedialer_test.go index 89373e362ca2..58e0bb517e44 100644 --- a/pkg/rpc/nodedialer/nodedialer_test.go +++ b/pkg/rpc/nodedialer/nodedialer_test.go @@ -129,8 +129,7 @@ func TestConcurrentCancellationAndTimeout(t *testing.T) { time.Sleep(randDuration(time.Millisecond)) _, err := nd.Dial(iCtx, 1, rpc.DefaultClass) if err != nil && - err != context.Canceled && - err != context.DeadlineExceeded { + !errors.IsAny(err, context.Canceled, context.DeadlineExceeded) { t.Errorf("got an unexpected error from Dial: %v", err) } wg.Done() @@ -178,9 +177,7 @@ func TestDisconnectsTrip(t *testing.T) { errChan := make(chan error, N) shouldTrip := func(err error) bool { return err != nil && - err != context.DeadlineExceeded && - err != context.Canceled && - errors.Cause(err) != circuit.ErrBreakerOpen + !errors.IsAny(err, context.DeadlineExceeded, context.Canceled, circuit.ErrBreakerOpen) } var wg sync.WaitGroup for i := 0; i < N; i++ { diff --git a/pkg/rpc/stats_handler_test.go b/pkg/rpc/stats_handler_test.go index 989e50058860..06551dfe6b99 100644 --- a/pkg/rpc/stats_handler_test.go +++ b/pkg/rpc/stats_handler_test.go @@ -25,6 +25,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/util/stop" "github.com/cockroachdb/cockroach/pkg/util/timeutil" "github.com/cockroachdb/cockroach/pkg/util/uuid" + "github.com/cockroachdb/errors" "google.golang.org/grpc/stats" ) @@ -134,7 +135,7 @@ func TestStatsHandlerWithHeartbeats(t *testing.T) { // Wait for the connection & successful heartbeat. testutils.SucceedsSoon(t, func() error { err := clientCtx.TestingConnHealth(remoteAddr, serverNodeID) - if err != nil && err != ErrNotHeartbeated { + if err != nil && !errors.Is(err, ErrNotHeartbeated) { t.Fatal(err) } return err diff --git a/pkg/server/admin_test.go b/pkg/server/admin_test.go index 280a79fe2fdd..15ec73741a44 100644 --- a/pkg/server/admin_test.go +++ b/pkg/server/admin_test.go @@ -223,7 +223,7 @@ func TestAdminDebugRedirect(t *testing.T) { } resp, err := client.Get(origURL) - if urlError, ok := err.(*url.Error); ok && urlError.Err == redirectAttemptedError { + if urlError, ok := err.(*url.Error); ok && errors.Is(urlError.Err, redirectAttemptedError) { // Ignore the redirectAttemptedError. err = nil } diff --git a/pkg/server/server.go b/pkg/server/server.go index 1a54566fe22d..fa2da2cd4ef6 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -1934,7 +1934,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // -v http://localhost:8080/favicon.ico > /dev/null // // which results in a 304 Not Modified. - if err := gzw.Close(); err != nil && err != http.ErrBodyNotAllowed { + if err := gzw.Close(); err != nil && !errors.Is(err, http.ErrBodyNotAllowed) { ctx := s.AnnotateCtx(r.Context()) log.Warningf(ctx, "error closing gzip response writer: %v", err) } diff --git a/pkg/server/version_cluster_test.go b/pkg/server/version_cluster_test.go index 43e9f038dd18..b4c5861a9d6c 100644 --- a/pkg/server/version_cluster_test.go +++ b/pkg/server/version_cluster_test.go @@ -51,7 +51,7 @@ func (th *testClusterWithHelpers) getVersionFromShow(i int) string { func (th *testClusterWithHelpers) getVersionFromSelect(i int) string { var version string if err := th.ServerConn(i).QueryRow("SELECT value FROM system.settings WHERE name = 'version'").Scan(&version); err != nil { - if err == gosql.ErrNoRows { + if errors.Is(err, gosql.ErrNoRows) { return "" } th.Fatalf("%d: %s (%T)", i, err, err) diff --git a/pkg/sql/comment_on_column_test.go b/pkg/sql/comment_on_column_test.go index aba55e7b2533..2396719dc384 100644 --- a/pkg/sql/comment_on_column_test.go +++ b/pkg/sql/comment_on_column_test.go @@ -18,6 +18,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/tests" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" "github.com/cockroachdb/cockroach/pkg/util/leaktest" + "github.com/cockroachdb/errors" ) func TestCommentOnColumn(t *testing.T) { @@ -134,7 +135,7 @@ func TestCommentOnColumnWhenDropTable(t *testing.T) { row := db.QueryRow(`SELECT comment FROM system.comments LIMIT 1`) var comment string err := row.Scan(&comment) - if err != gosql.ErrNoRows { + if !errors.Is(err, gosql.ErrNoRows) { if err != nil { t.Fatal(err) } @@ -169,7 +170,7 @@ func TestCommentOnColumnWhenDropColumn(t *testing.T) { row := db.QueryRow(`SELECT comment FROM system.comments LIMIT 1`) var comment string err := row.Scan(&comment) - if err != gosql.ErrNoRows { + if !errors.Is(err, gosql.ErrNoRows) { if err != nil { t.Fatal(err) } diff --git a/pkg/sql/comment_on_database_test.go b/pkg/sql/comment_on_database_test.go index b46f0dad91ba..595cfdac19d6 100644 --- a/pkg/sql/comment_on_database_test.go +++ b/pkg/sql/comment_on_database_test.go @@ -18,6 +18,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/tests" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" "github.com/cockroachdb/cockroach/pkg/util/leaktest" + "github.com/cockroachdb/errors" ) func TestCommentOnDatabase(t *testing.T) { @@ -95,7 +96,7 @@ func TestCommentOnDatabaseWhenDrop(t *testing.T) { row := db.QueryRow(`SELECT comment FROM system.comments LIMIT 1`) var comment string err := row.Scan(&comment) - if err != gosql.ErrNoRows { + if !errors.Is(err, gosql.ErrNoRows) { if err != nil { t.Fatal(err) } diff --git a/pkg/sql/comment_on_index_test.go b/pkg/sql/comment_on_index_test.go index 5c0f236c2725..7d06da41bb08 100644 --- a/pkg/sql/comment_on_index_test.go +++ b/pkg/sql/comment_on_index_test.go @@ -18,6 +18,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/tests" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" "github.com/cockroachdb/cockroach/pkg/util/leaktest" + "github.com/cockroachdb/errors" ) func TestCommentOnIndex(t *testing.T) { @@ -99,7 +100,7 @@ func TestCommentOnIndexWhenDropTable(t *testing.T) { row := db.QueryRow(`SELECT comment FROM system.comments LIMIT 1`) var comment string err := row.Scan(&comment) - if err != gosql.ErrNoRows { + if !errors.Is(err, gosql.ErrNoRows) { if err != nil { t.Fatal(err) } @@ -134,7 +135,7 @@ func TestCommentOnIndexWhenDropIndex(t *testing.T) { row := db.QueryRow(`SELECT comment FROM system.comments LIMIT 1`) var comment string err := row.Scan(&comment) - if err != gosql.ErrNoRows { + if !errors.Is(err, gosql.ErrNoRows) { if err != nil { t.Fatal(err) } diff --git a/pkg/sql/comment_on_table_test.go b/pkg/sql/comment_on_table_test.go index 2ca07e02e162..aaf1fb904d99 100644 --- a/pkg/sql/comment_on_table_test.go +++ b/pkg/sql/comment_on_table_test.go @@ -18,6 +18,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/tests" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" "github.com/cockroachdb/cockroach/pkg/util/leaktest" + "github.com/cockroachdb/errors" ) func TestCommentOnTable(t *testing.T) { @@ -99,7 +100,7 @@ func TestCommentOnTableWhenDrop(t *testing.T) { row := db.QueryRow(`SELECT comment FROM system.comments LIMIT 1`) var comment string err := row.Scan(&comment) - if err != gosql.ErrNoRows { + if !errors.Is(err, gosql.ErrNoRows) { if err != nil { t.Fatal(err) } diff --git a/pkg/sql/conn_executor.go b/pkg/sql/conn_executor.go index 16e0d2c1f1c2..65a40547c673 100644 --- a/pkg/sql/conn_executor.go +++ b/pkg/sql/conn_executor.go @@ -1297,7 +1297,7 @@ func (ex *connExecutor) run( var err error if err = ex.execCmd(ex.Ctx()); err != nil { - if err == io.EOF || err == errDrainingComplete { + if errors.IsAny(err, io.EOF, errDrainingComplete) { return nil } return err diff --git a/pkg/sql/crdb_internal.go b/pkg/sql/crdb_internal.go index 66ddda8b792c..6dfe4f6f9190 100644 --- a/pkg/sql/crdb_internal.go +++ b/pkg/sql/crdb_internal.go @@ -2454,7 +2454,7 @@ CREATE TABLE crdb_internal.zones ( for i, s := range subzones { index, err := table.FindIndexByID(sqlbase.IndexID(s.IndexID)) if err != nil { - if err == sqlbase.ErrIndexGCMutationsList { + if errors.Is(err, sqlbase.ErrIndexGCMutationsList) { continue } return err diff --git a/pkg/sql/descriptor.go b/pkg/sql/descriptor.go index fb311a7f0657..71e456a17edb 100644 --- a/pkg/sql/descriptor.go +++ b/pkg/sql/descriptor.go @@ -231,7 +231,7 @@ func lookupDescriptorByID( var err error desc, err = lookupFn() if err != nil { - if err == sqlbase.ErrDescriptorNotFound { + if errors.Is(err, sqlbase.ErrDescriptorNotFound) { continue } return nil, false, err diff --git a/pkg/sql/distsql_physical_planner.go b/pkg/sql/distsql_physical_planner.go index 59bf63e8e275..43e15ae2262c 100644 --- a/pkg/sql/distsql_physical_planner.go +++ b/pkg/sql/distsql_physical_planner.go @@ -671,7 +671,7 @@ func (h *distSQLNodeHealth) check(ctx context.Context, nodeID roachpb.NodeID) er // writing). This is better than having it used in 100% of cases // (until the liveness check below kicks in). err := h.connHealth(nodeID, rpc.DefaultClass) - if err != nil && err != rpc.ErrNotHeartbeated { + if err != nil && !errors.Is(err, rpc.ErrNotHeartbeated) { // This host is known to be unhealthy. Don't use it (use the gateway // instead). Note: this can never happen for our nodeID (which // always has its address in the nodeMap). diff --git a/pkg/sql/flowinfra/flow_registry_test.go b/pkg/sql/flowinfra/flow_registry_test.go index c189fb830e34..fafaa19adcda 100644 --- a/pkg/sql/flowinfra/flow_registry_test.go +++ b/pkg/sql/flowinfra/flow_registry_test.go @@ -650,7 +650,7 @@ func TestFlowCancelPartiallyBlocked(t *testing.T) { // flow canceled error. _, meta := right.Next() - if meta.Err != sqlbase.QueryCanceledError { + if !errors.Is(meta.Err, sqlbase.QueryCanceledError) { t.Fatal("expected query canceled, found", meta.Err) } @@ -659,7 +659,7 @@ func TestFlowCancelPartiallyBlocked(t *testing.T) { _, _ = left.Next() _, meta = left.Next() - if meta.Err != sqlbase.QueryCanceledError { + if !errors.Is(meta.Err, sqlbase.QueryCanceledError) { t.Fatal("expected query canceled, found", meta.Err) } } diff --git a/pkg/sql/lease.go b/pkg/sql/lease.go index a44632f1c4c1..ea5674326319 100644 --- a/pkg/sql/lease.go +++ b/pkg/sql/lease.go @@ -1167,8 +1167,7 @@ func purgeOldVersions( // active lease, so that it doesn't get released when removeInactives() // is called below. Release this lease after calling removeInactives(). table, _, err := t.findForTimestamp(ctx, m.clock.Now()) - if _, ok := err.(*inactiveTableError); ok || err == nil { - isInactive := ok + if isInactive := errors.HasType(err, (*inactiveTableError)(nil)); err == nil || isInactive { removeInactives(isInactive) if table != nil { s, err := t.release(&table.ImmutableTableDescriptor, m.removeOnceDereferenced()) diff --git a/pkg/sql/opt_catalog.go b/pkg/sql/opt_catalog.go index f4a36988278b..2375f40dc9be 100644 --- a/pkg/sql/opt_catalog.go +++ b/pkg/sql/opt_catalog.go @@ -195,7 +195,7 @@ func (oc *optCatalog) ResolveDataSourceByID( tableLookup, err := oc.planner.LookupTableByID(ctx, sqlbase.ID(dataSourceID)) if err != nil || tableLookup.IsAdding { - if err == sqlbase.ErrDescriptorNotFound || tableLookup.IsAdding { + if errors.Is(err, sqlbase.ErrDescriptorNotFound) || tableLookup.IsAdding { return nil, tableLookup.IsAdding, sqlbase.NewUndefinedRelationError(&tree.TableRef{TableID: int64(dataSourceID)}) } return nil, false, err diff --git a/pkg/sql/pgwire/conn_test.go b/pkg/sql/pgwire/conn_test.go index 68fd73998007..ba600c42f9ce 100644 --- a/pkg/sql/pgwire/conn_test.go +++ b/pkg/sql/pgwire/conn_test.go @@ -924,7 +924,7 @@ func TestReadTimeoutConnExits(t *testing.T) { default: } cancel() - if err := <-errChan; err != context.Canceled { + if err := <-errChan; !errors.Is(err, context.Canceled) { t.Fatalf("unexpected error: %v", err) } } diff --git a/pkg/sql/pgwire/pgwire_test.go b/pkg/sql/pgwire/pgwire_test.go index d02d06f49b42..f45ade1d625a 100644 --- a/pkg/sql/pgwire/pgwire_test.go +++ b/pkg/sql/pgwire/pgwire_test.go @@ -193,13 +193,13 @@ func TestPGWireDrainOngoingTxns(t *testing.T) { // because we must wait (since we told the pgServer not to) until the // connection registers the cancellation and closes itself. testutils.SucceedsSoon(t, func() error { - if _, err := txn.Exec("SELECT 1"); err != driver.ErrBadConn { + if _, err := txn.Exec("SELECT 1"); !errors.Is(err, driver.ErrBadConn) { return errors.Errorf("unexpected error: %v", err) } return nil }) - if err := txn.Commit(); err != driver.ErrBadConn { + if err := txn.Commit(); !errors.Is(err, driver.ErrBadConn) { t.Fatalf("unexpected error: %v", err) } @@ -224,7 +224,8 @@ func TestPGWireDrainOngoingTxns(t *testing.T) { } if err := txn.Commit(); err == nil || - (err != driver.ErrBadConn && !strings.Contains(err.Error(), "connection reset by peer")) { + (!errors.Is(err, driver.ErrBadConn) && + !strings.Contains(err.Error(), "connection reset by peer")) { t.Fatalf("unexpected error: %v", err) } diff --git a/pkg/sql/planner.go b/pkg/sql/planner.go index 5d17b835e315..979ba9574561 100644 --- a/pkg/sql/planner.go +++ b/pkg/sql/planner.go @@ -458,7 +458,7 @@ func (p *planner) LookupTableByID(ctx context.Context, tableID sqlbase.ID) (row. flags := tree.ObjectLookupFlags{CommonLookupFlags: tree.CommonLookupFlags{AvoidCached: p.avoidCachedDescriptors}} table, err := p.Tables().getTableVersionByID(ctx, p.txn, tableID, flags) if err != nil { - if err == errTableAdding { + if errors.Is(err, errTableAdding) { return row.TableEntry{IsAdding: true}, nil } return row.TableEntry{}, err diff --git a/pkg/sql/row/fk_existence_delete.go b/pkg/sql/row/fk_existence_delete.go index 45cbb3eee59e..c2c9ee8155dc 100644 --- a/pkg/sql/row/fk_existence_delete.go +++ b/pkg/sql/row/fk_existence_delete.go @@ -91,7 +91,7 @@ func makeFkExistenceCheckHelperForDelete( } fk, err := makeFkExistenceCheckBaseHelper(txn, codec, otherTables, fakeRef, searchIdx, mutatedIdx, colMap, alloc, CheckDeletes) - if err == errSkipUnusedFK { + if errors.Is(err, errSkipUnusedFK) { continue } if err != nil { diff --git a/pkg/sql/row/fk_existence_insert.go b/pkg/sql/row/fk_existence_insert.go index a13fb4dfe601..481b6cfa19c2 100644 --- a/pkg/sql/row/fk_existence_insert.go +++ b/pkg/sql/row/fk_existence_insert.go @@ -82,7 +82,7 @@ func makeFkExistenceCheckHelperForInsert( return h, withLink } fk, err := makeFkExistenceCheckBaseHelper(txn, codec, otherTables, ref, searchIdx, mutatedIdx, colMap, alloc, CheckInserts) - if err == errSkipUnusedFK { + if errors.Is(err, errSkipUnusedFK) { continue } if err != nil { diff --git a/pkg/sql/rowexec/joinreader_test.go b/pkg/sql/rowexec/joinreader_test.go index b751085856b1..7321ca6d557b 100644 --- a/pkg/sql/rowexec/joinreader_test.go +++ b/pkg/sql/rowexec/joinreader_test.go @@ -677,7 +677,7 @@ func TestJoinReaderDrain(t *testing.T) { if row != nil { t.Fatalf("row was pushed unexpectedly: %s", row.String(sqlbase.OneIntCol)) } - if meta.Err != expectedMetaErr { + if !errors.Is(meta.Err, expectedMetaErr) { t.Fatalf("unexpected error in metadata: %v", meta.Err) } diff --git a/pkg/sql/rowflow/routers_test.go b/pkg/sql/rowflow/routers_test.go index 37e2a7d338af..b9271ad382f5 100644 --- a/pkg/sql/rowflow/routers_test.go +++ b/pkg/sql/rowflow/routers_test.go @@ -497,7 +497,7 @@ func TestMetadataIsForwarded(t *testing.T) { t.Fatalf("expected status %d, got: %d", execinfra.NeedMoreRows, consumerStatus) } _, meta := chans[0].Next() - if meta.Err != err1 { + if !errors.Is(meta.Err, err1) { t.Fatalf("unexpected meta.Err %v, expected %s", meta.Err, err1) } } @@ -510,7 +510,7 @@ func TestMetadataIsForwarded(t *testing.T) { t.Fatalf("expected status %d, got: %d", execinfra.NeedMoreRows, consumerStatus) } _, meta := chans[0].Next() - if meta.Err != err2 { + if !errors.Is(meta.Err, err2) { t.Fatalf("unexpected meta.Err %v, expected %s", meta.Err, err2) } } @@ -528,7 +528,7 @@ func TestMetadataIsForwarded(t *testing.T) { // try to go to 0 for a little while. select { case d := <-chans[1].C: - if d.Meta.Err != err3 { + if !errors.Is(d.Meta.Err, err3) { t.Fatalf("unexpected meta.Err %v, expected %s", d.Meta.Err, err3) } return nil diff --git a/pkg/sql/run_control_test.go b/pkg/sql/run_control_test.go index 24cd0e5667c2..fb928a5cd870 100644 --- a/pkg/sql/run_control_test.go +++ b/pkg/sql/run_control_test.go @@ -268,7 +268,7 @@ func testCancelSession(t *testing.T, hasActiveSession bool) { _, err = conn1.ExecContext(ctx, "SELECT 1") } - if err != gosqldriver.ErrBadConn { + if !errors.Is(err, gosqldriver.ErrBadConn) { t.Fatalf("session not canceled; actual error: %s", err) } } @@ -310,7 +310,7 @@ func TestCancelMultipleSessions(t *testing.T) { // Verify that the connections on node 1 are closed. for i := 0; i < 2; i++ { _, err := conns[i].ExecContext(ctx, "SELECT 1") - if err != gosqldriver.ErrBadConn { + if !errors.Is(err, gosqldriver.ErrBadConn) { t.Fatalf("session %d not canceled; actual error: %s", i, err) } } diff --git a/pkg/sql/schema_changer_test.go b/pkg/sql/schema_changer_test.go index 4a403c6d301a..0382648679c4 100644 --- a/pkg/sql/schema_changer_test.go +++ b/pkg/sql/schema_changer_test.go @@ -4021,7 +4021,7 @@ CREATE TABLE t.test (k INT PRIMARY KEY, v INT, pi DECIMAL REFERENCES t.pi (d) DE _, err = sqlbase.GetTableDescFromID(ctx, txn, keys.SystemSQLCodec, tableDesc.ID) return err }); err != nil { - if err == sqlbase.ErrDescriptorNotFound { + if errors.Is(err, sqlbase.ErrDescriptorNotFound) { return nil } return err @@ -4762,7 +4762,7 @@ func TestCancelSchemaChangeContext(t *testing.T) { t.Error(err) } if _, err := conn.ExecContext( - ctx, `CREATE INDEX foo ON t.public.test (v)`); err != driver.ErrBadConn { + ctx, `CREATE INDEX foo ON t.public.test (v)`); !errors.Is(err, driver.ErrBadConn) { t.Errorf("unexpected err = %+v", err) } }() diff --git a/pkg/sql/set_zone_config.go b/pkg/sql/set_zone_config.go index 3f06ee85c579..92a16f4aad15 100644 --- a/pkg/sql/set_zone_config.go +++ b/pkg/sql/set_zone_config.go @@ -415,7 +415,7 @@ func (n *setZoneConfigNode) startExec(params runParams) error { _, completeZone, completeSubzone, err := GetZoneConfigInTxn(params.ctx, params.p.txn, uint32(targetID), index, partition, n.setDefault) - if err == errNoZoneConfigApplies { + if errors.Is(err, errNoZoneConfigApplies) { // No zone config yet. // // GetZoneConfigInTxn will fail with errNoZoneConfigApplies when diff --git a/pkg/sql/show_zone_config.go b/pkg/sql/show_zone_config.go index b974dc9ee3db..ad0d1292b665 100644 --- a/pkg/sql/show_zone_config.go +++ b/pkg/sql/show_zone_config.go @@ -126,7 +126,7 @@ func getShowZoneConfigRow( subZoneIdx := uint32(0) zoneID, zone, subzone, err := GetZoneConfigInTxn(ctx, p.txn, uint32(targetID), index, partition, false /* getInheritedDefault */) - if err == errNoZoneConfigApplies { + if errors.Is(err, errNoZoneConfigApplies) { // TODO(benesch): This shouldn't be the caller's responsibility; // GetZoneConfigInTxn should just return the default zone config if no zone // config applies. diff --git a/pkg/sql/sqlbase/structured.go b/pkg/sql/sqlbase/structured.go index 8e67e59077b4..f988735f4bab 100644 --- a/pkg/sql/sqlbase/structured.go +++ b/pkg/sql/sqlbase/structured.go @@ -992,7 +992,7 @@ func maybeUpgradeForeignKeyRepOnIndex( if _, ok := otherUnupgradedTables[ref.Table]; !ok { tbl, err := getTableDescFromIDRaw(ctx, protoGetter, codec, ref.Table) if err != nil { - if err == ErrDescriptorNotFound && skipFKsWithNoMatchingTable { + if errors.Is(err, ErrDescriptorNotFound) && skipFKsWithNoMatchingTable { // Ignore this FK and keep going. } else { return false, err @@ -1031,7 +1031,7 @@ func maybeUpgradeForeignKeyRepOnIndex( if _, ok := otherUnupgradedTables[ref.Table]; !ok { tbl, err := getTableDescFromIDRaw(ctx, protoGetter, codec, ref.Table) if err != nil { - if err == ErrDescriptorNotFound && skipFKsWithNoMatchingTable { + if errors.Is(err, ErrDescriptorNotFound) && skipFKsWithNoMatchingTable { // Ignore this FK and keep going. } else { return false, err @@ -2215,10 +2215,10 @@ func (desc *TableDescriptor) validatePartitioningDescriptor( return fmt.Errorf("partitions %s and %s overlap", overlaps[0].(partitionInterval).name, p.Name) } - if err := tree.Insert(pi, false /* fast */); err == interval.ErrEmptyRange { + if err := tree.Insert(pi, false /* fast */); errors.Is(err, interval.ErrEmptyRange) { return fmt.Errorf("PARTITION %s: empty range: lower bound %s is equal to upper bound %s", p.Name, fromDatums, toDatums) - } else if err == interval.ErrInvertedRange { + } else if errors.Is(err, interval.ErrInvertedRange) { return fmt.Errorf("PARTITION %s: empty range: lower bound %s is greater than upper bound %s", p.Name, fromDatums, toDatums) } else if err != nil { diff --git a/pkg/sql/table.go b/pkg/sql/table.go index e62b1773f46b..79061abc7985 100644 --- a/pkg/sql/table.go +++ b/pkg/sql/table.go @@ -60,21 +60,25 @@ func (p *planner) getVirtualTabler() VirtualTabler { var errTableAdding = errors.New("table is being added") type inactiveTableError struct { - error + cause error } +func (i *inactiveTableError) Error() string { return i.cause.Error() } + +func (i *inactiveTableError) Unwrap() error { return i.cause } + // FilterTableState inspects the state of a given table and returns an error if // the state is anything but PUBLIC. The error describes the state of the table. func FilterTableState(tableDesc *sqlbase.TableDescriptor) error { switch tableDesc.State { case sqlbase.TableDescriptor_DROP: - return inactiveTableError{errors.New("table is being dropped")} + return &inactiveTableError{errors.New("table is being dropped")} case sqlbase.TableDescriptor_OFFLINE: err := errors.Errorf("table %q is offline", tableDesc.Name) if tableDesc.OfflineReason != "" { err = errors.Errorf("table %q is offline: %s", tableDesc.Name, tableDesc.OfflineReason) } - return inactiveTableError{err} + return &inactiveTableError{err} case sqlbase.TableDescriptor_ADD: return errTableAdding case sqlbase.TableDescriptor_PUBLIC: @@ -402,7 +406,8 @@ func (tc *TableCollection) getTableVersion( // Read the descriptor from the store in the face of some specific errors // because of a known limitation of AcquireByName. See the known // limitations of AcquireByName for details. - if _, ok := err.(inactiveTableError); ok || err == sqlbase.ErrDescriptorNotFound { + if errors.HasType(err, (*inactiveTableError)(nil)) || + errors.Is(err, sqlbase.ErrDescriptorNotFound) { return readTableFromStore() } // Lease acquisition failed with some other error. This we don't @@ -466,7 +471,7 @@ func (tc *TableCollection) getTableVersionByID( readTimestamp := txn.ReadTimestamp() table, expiration, err := tc.leaseMgr.Acquire(ctx, readTimestamp, tableID) if err != nil { - if err == sqlbase.ErrDescriptorNotFound { + if errors.Is(err, sqlbase.ErrDescriptorNotFound) { // Transform the descriptor error into an error that references the // table's ID. return nil, sqlbase.NewUndefinedRelationError( @@ -717,7 +722,7 @@ func (tc *TableCollection) getUncommittedTable( tn.Table(), ) { // Right state? - if err = FilterTableState(mutTbl.TableDesc()); err != nil && err != errTableAdding { + if err = FilterTableState(mutTbl.TableDesc()); err != nil && !errors.Is(err, errTableAdding) { if !required { // If it's not required here, we simply say we don't have it. err = nil diff --git a/pkg/sql/virtual_table.go b/pkg/sql/virtual_table.go index e41f8b06e723..c0472ba75a0d 100644 --- a/pkg/sql/virtual_table.go +++ b/pkg/sql/virtual_table.go @@ -15,6 +15,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" + "github.com/cockroachdb/errors" ) // virtualTableGenerator is the function signature for the virtualTableNode @@ -107,7 +108,7 @@ func setupGenerator( err := worker(funcRowPusher(addRow)) // If the query was canceled, next() will already return a // QueryCanceledError, so just exit here. - if err == sqlbase.QueryCanceledError { + if errors.Is(err, sqlbase.QueryCanceledError) { return } diff --git a/pkg/sql/zone_config.go b/pkg/sql/zone_config.go index df1a25ad4e27..148e6645c574 100644 --- a/pkg/sql/zone_config.go +++ b/pkg/sql/zone_config.go @@ -162,7 +162,7 @@ func ZoneConfigHook( } zoneID, zone, _, placeholder, err := getZoneConfig( id, getKey, false /* getInheritedDefault */) - if err == errNoZoneConfigApplies { + if errors.Is(err, errNoZoneConfigApplies) { return nil, nil, true, nil } else if err != nil { return nil, nil, false, err @@ -280,7 +280,7 @@ func resolveZone(ctx context.Context, txn *kv.Txn, zs *tree.ZoneSpecifier) (sqlb }, ) if err != nil { - if err == errMissingKey { + if errors.Is(err, errMissingKey) { return 0, zoneSpecifierNotFoundError(*zs) } return 0, err diff --git a/pkg/storage/cloud/gcs_storage.go b/pkg/storage/cloud/gcs_storage.go index b4d536d8cf6b..3aacf19415ed 100644 --- a/pkg/storage/cloud/gcs_storage.go +++ b/pkg/storage/cloud/gcs_storage.go @@ -247,7 +247,7 @@ func (g *gcsStorage) ListFiles(ctx context.Context, patternSuffix string) ([]str for { attrs, err := it.Next() - if err == iterator.Done { + if errors.Is(err, iterator.Done) { break } if err != nil { diff --git a/pkg/storage/pebble.go b/pkg/storage/pebble.go index 05a29595a351..36f0b76a19aa 100644 --- a/pkg/storage/pebble.go +++ b/pkg/storage/pebble.go @@ -610,7 +610,7 @@ func (p *Pebble) Get(key MVCCKey) ([]byte, error) { ret = retCopy closer.Close() } - if err == pebble.ErrNotFound || len(ret) == 0 { + if errors.Is(err, pebble.ErrNotFound) || len(ret) == 0 { return nil, nil } return ret, err @@ -642,7 +642,7 @@ func (p *Pebble) GetProto( closer.Close() return true, keyBytes, valBytes, err } - if err == pebble.ErrNotFound { + if errors.Is(err, pebble.ErrNotFound) { return false, 0, 0, nil } return false, 0, 0, err @@ -1243,7 +1243,7 @@ func (p *pebbleSnapshot) Get(key MVCCKey) ([]byte, error) { ret = retCopy closer.Close() } - if err == pebble.ErrNotFound || len(ret) == 0 { + if errors.Is(err, pebble.ErrNotFound) || len(ret) == 0 { return nil, nil } return ret, err @@ -1267,7 +1267,7 @@ func (p *pebbleSnapshot) GetProto( closer.Close() return true, keyBytes, valBytes, err } - if err == pebble.ErrNotFound { + if errors.Is(err, pebble.ErrNotFound) { return false, 0, 0, nil } return false, 0, 0, err diff --git a/pkg/storage/pebble_batch.go b/pkg/storage/pebble_batch.go index c3030451c029..5c6185676393 100644 --- a/pkg/storage/pebble_batch.go +++ b/pkg/storage/pebble_batch.go @@ -16,6 +16,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/util/hlc" "github.com/cockroachdb/cockroach/pkg/util/protoutil" + "github.com/cockroachdb/errors" "github.com/cockroachdb/pebble" ) @@ -123,7 +124,7 @@ func (p *pebbleBatch) Get(key MVCCKey) ([]byte, error) { ret = retCopy closer.Close() } - if err == pebble.ErrNotFound || len(ret) == 0 { + if errors.Is(err, pebble.ErrNotFound) || len(ret) == 0 { return nil, nil } return ret, err @@ -158,7 +159,7 @@ func (p *pebbleBatch) GetProto( closer.Close() return true, keyBytes, valBytes, err } - if err == pebble.ErrNotFound { + if errors.Is(err, pebble.ErrNotFound) { return false, 0, 0, nil } return false, 0, 0, err diff --git a/pkg/testutils/lint/passes/errcmp/errcmp.go b/pkg/testutils/lint/passes/errcmp/errcmp.go new file mode 100644 index 000000000000..019a0c9c7688 --- /dev/null +++ b/pkg/testutils/lint/passes/errcmp/errcmp.go @@ -0,0 +1,108 @@ +// Copyright 2020 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +// Package errcmp defines an Analyzer which checks +// for usage of errors.Is instead of direct ==/!= comparisons. +package errcmp + +import ( + "go/ast" + "go/token" + "go/types" + "strings" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/ast/inspector" +) + +// Doc documents this pass. +const Doc = `check for comparison of error objects` + +var errorType = types.Universe.Lookup("error").Type() + +// Analyzer checks for usage of errors.Is instead of direct ==/!= +// comparisons. +var Analyzer = &analysis.Analyzer{ + Name: "errcmp", + Doc: Doc, + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: run, +} + +func run(pass *analysis.Pass) (interface{}, error) { + inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + + // Our analyzer just wants to see comparisons and casts. + nodeFilter := []ast.Node{ + (*ast.BinaryExpr)(nil), + // (*ast.TypeAssertExpr)(nil), + } + + // Now traverse the ASTs. + inspect.Preorder(nodeFilter, func(n ast.Node) { + // Catch-all for possible bugs in the linter code. + defer func() { + if r := recover(); r != nil { + if err, ok := r.(error); ok { + pass.Reportf(n.Pos(), "internal linter error: %v", err) + return + } + panic(r) + } + }() + + if cmp, ok := n.(*ast.BinaryExpr); ok { + checkErrCmp(pass, cmp) + return + } + // At a cast. + // TBD + }) + + return nil, nil +} + +func isEOFError(e ast.Expr) bool { + if s, ok := e.(*ast.SelectorExpr); ok { + if io, ok := s.X.(*ast.Ident); ok && io.Name == "io" && io.Obj == (*ast.Object)(nil) { + if s.Sel.Name == "EOF" { + return true + } + } + } + return false +} + +func checkErrCmp(pass *analysis.Pass, binaryExpr *ast.BinaryExpr) { + switch binaryExpr.Op { + case token.NEQ, token.EQL: + if pass.TypesInfo.Types[binaryExpr.X].Type == errorType && + !pass.TypesInfo.Types[binaryExpr.Y].IsNil() { + // We have a special case: when the RHS is io.EOF. + // This is nearly always used with APIs that return + // it undecorated. + if isEOFError(binaryExpr.Y) { + return + } + + pass.Reportf(binaryExpr.OpPos, escNl(`use errors.Is instead of a direct comparison +For example: + if errors.Is(err, errMyOwnErrReference) { + ... + } +`)) + } + } +} + +func escNl(msg string) string { + return strings.ReplaceAll(msg, "\n", "\\n++") +} diff --git a/pkg/testutils/net.go b/pkg/testutils/net.go index d730be1da49f..123e493f7ba5 100644 --- a/pkg/testutils/net.go +++ b/pkg/testutils/net.go @@ -382,7 +382,7 @@ func (c *PartitionableConn) copyFromBuffer( } } else if err == nil { err = io.EOF - } else if err == errEAgain { + } else if errors.Is(err, errEAgain) { continue } if err != nil { diff --git a/pkg/testutils/zerofields/no_zero_field_test.go b/pkg/testutils/zerofields/no_zero_field_test.go index 906f1aea08f9..d345a8e8884e 100644 --- a/pkg/testutils/zerofields/no_zero_field_test.go +++ b/pkg/testutils/zerofields/no_zero_field_test.go @@ -10,7 +10,11 @@ package zerofields -import "testing" +import ( + "testing" + + "github.com/cockroachdb/errors" +) func TestNoZeroField(t *testing.T) { type foo struct { @@ -31,12 +35,12 @@ func TestNoZeroField(t *testing.T) { } testFoo = testFooNonZero testFoo.Y = 0 - if err, exp := NoZeroField(&testFoo), (zeroFieldErr{"Y"}); err != exp { + if err, exp := NoZeroField(&testFoo), (zeroFieldErr{"Y"}); !errors.Is(err, exp) { t.Fatalf("expected error %v, found %v", exp, err) } testFoo = testFooNonZero testFoo.Z.B = 0 - if err, exp := NoZeroField(&testFoo), (zeroFieldErr{"Z.B"}); err != exp { + if err, exp := NoZeroField(&testFoo), (zeroFieldErr{"Z.B"}); !errors.Is(err, exp) { t.Fatalf("expected error %v, found %v", exp, err) } } diff --git a/pkg/util/contextutil/context.go b/pkg/util/contextutil/context.go index 3b117bef68ff..b6c1eec62b3c 100644 --- a/pkg/util/contextutil/context.go +++ b/pkg/util/contextutil/context.go @@ -104,7 +104,7 @@ func (t *TimeoutError) Format(s fmt.State, verb rune) { errors.FormatError(t, s, // FormatError implements errors.Formatter. func (t *TimeoutError) FormatError(p errors.Printer) error { p.Printf("operation %q timed out after %s", t.operation, t.duration) - if t.cause != context.DeadlineExceeded { + if errors.UnwrapOnce(t.cause) != nil { // If there were details (wrappers, stack trace etc.) ensure // they get printed. return t.cause @@ -133,7 +133,7 @@ func RunWithTimeout( ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() err := fn(ctx) - if err != nil && ctx.Err() == context.DeadlineExceeded { + if err != nil && errors.Is(ctx.Err(), context.DeadlineExceeded) { err = &TimeoutError{ operation: op, duration: timeout, diff --git a/pkg/util/contextutil/context_test.go b/pkg/util/contextutil/context_test.go index 802349402c4d..0f1e184a3366 100644 --- a/pkg/util/contextutil/context_test.go +++ b/pkg/util/contextutil/context_test.go @@ -45,7 +45,7 @@ func TestRunWithTimeout(t *testing.T) { if !netError.Timeout() || !netError.Temporary() { t.Fatal("RunWithTimeout should return a timeout and temporary error") } - if errors.Cause(err) != context.DeadlineExceeded { + if !errors.Is(err, context.DeadlineExceeded) { t.Fatalf("RunWithTimeout should return an error with a DeadlineExceeded cause") } @@ -64,7 +64,7 @@ func TestRunWithTimeout(t *testing.T) { if !netError.Timeout() || !netError.Temporary() { t.Fatal("RunWithTimeout should return a timeout and temporary error") } - if errors.Cause(err) != context.DeadlineExceeded { + if !errors.Is(err, context.DeadlineExceeded) { t.Fatalf("RunWithTimeout should return an error with a DeadlineExceeded cause") } } @@ -88,7 +88,7 @@ func TestRunWithTimeoutWithoutDeadlineExceeded(t *testing.T) { if !netError.Timeout() || !netError.Temporary() { t.Fatal("RunWithTimeout should return a timeout and temporary error") } - if errors.Cause(err) != notContextDeadlineExceeded { + if !errors.Is(err, notContextDeadlineExceeded) { t.Fatalf("RunWithTimeout should return an error caused by the underlying " + "returned error") } diff --git a/pkg/util/ctxgroup/ctxgroup_test.go b/pkg/util/ctxgroup/ctxgroup_test.go index 1c60ce89330f..730f905895cb 100644 --- a/pkg/util/ctxgroup/ctxgroup_test.go +++ b/pkg/util/ctxgroup/ctxgroup_test.go @@ -16,6 +16,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/util/leaktest" + "github.com/cockroachdb/errors" ) func TestErrorAfterCancel(t *testing.T) { @@ -36,7 +37,7 @@ func TestErrorAfterCancel(t *testing.T) { cancel() } - if err := g.Wait(); err != expErr { + if err := g.Wait(); !errors.Is(err, expErr) { t.Errorf("expected %v, got %v", expErr, err) } }) diff --git a/pkg/util/encoding/csv/reader.go b/pkg/util/encoding/csv/reader.go index 1623b85c2458..1f002d369ef1 100644 --- a/pkg/util/encoding/csv/reader.go +++ b/pkg/util/encoding/csv/reader.go @@ -96,7 +96,7 @@ func (e *ParseError) Format(s fmt.State, verb rune) { errors.FormatError(e, s, v // FormatError implements errors.Formatter. func (e *ParseError) FormatError(p errors.Printer) error { - if e.Err == ErrFieldCount { + if errors.Is(e.Err, ErrFieldCount) { p.Printf("record on line %d", e.Line) } else if e.StartLine != e.Line { p.Printf("record on line %d; parse error on line %d, column %d", e.StartLine, e.Line, e.Column) @@ -228,9 +228,9 @@ func (r *Reader) ReadAll() (records [][]string, err error) { // The result is only valid until the next call to readLine. func (r *Reader) readLine() ([]byte, error) { line, err := r.r.ReadSlice('\n') - if err == bufio.ErrBufferFull { + if errors.Is(err, bufio.ErrBufferFull) { r.rawBuffer = append(r.rawBuffer[:0], line...) - for err == bufio.ErrBufferFull { + for errors.Is(err, bufio.ErrBufferFull) { line, err = r.r.ReadSlice('\n') r.rawBuffer = append(r.rawBuffer, line...) } diff --git a/pkg/util/grpcutil/grpc_util.go b/pkg/util/grpcutil/grpc_util.go index 4a648acabd98..441583805a04 100644 --- a/pkg/util/grpcutil/grpc_util.go +++ b/pkg/util/grpcutil/grpc_util.go @@ -44,17 +44,17 @@ func IsLocalRequestContext(ctx context.Context) bool { // IsClosedConnection returns true if err's Cause is an error produced by gRPC // on closed connections. func IsClosedConnection(err error) bool { - err = errors.Cause(err) - if err == ErrCannotReuseClientConn { + if errors.Is(err, ErrCannotReuseClientConn) { return true } + err = errors.Cause(err) if s, ok := status.FromError(err); ok { if s.Code() == codes.Canceled || s.Code() == codes.Unavailable { return true } } - if err == context.Canceled || + if errors.Is(err, context.Canceled) || strings.Contains(err.Error(), "is closing") || strings.Contains(err.Error(), "tls: use of closed connection") || strings.Contains(err.Error(), "use of closed network connection") || diff --git a/pkg/util/hlc/hlc_test.go b/pkg/util/hlc/hlc_test.go index 74a7ca7a432b..9df2d1281b30 100644 --- a/pkg/util/hlc/hlc_test.go +++ b/pkg/util/hlc/hlc_test.go @@ -539,7 +539,7 @@ func TestResetAndRefreshHLCUpperBound(t *testing.T) { // Test Reset Upper Bound err = c.ResetHLCUpperBound(persistFn) a.True( - test.persistErr == err, + errors.Is(test.persistErr, err), fmt.Sprintf( "expected err %v not equal to actual err %v", test.persistErr, diff --git a/pkg/util/interval/range_group_test.go b/pkg/util/interval/range_group_test.go index fe9cb621858f..5dd9b4f413f5 100644 --- a/pkg/util/interval/range_group_test.go +++ b/pkg/util/interval/range_group_test.go @@ -533,7 +533,7 @@ func TestRangeGroupForEach(t *testing.T) { expRngs := test.rngs if throwingErr { expRngs = test.rngs[:test.errAfter] - if errSaw != errToThrow { + if !errors.Is(errSaw, errToThrow) { t.Errorf("expected error %v from RangeGroup.ForEach, found %v", errToThrow, errSaw) } } else { diff --git a/pkg/util/limit/limiter_test.go b/pkg/util/limit/limiter_test.go index 3a292c0d6c9c..a5c63a9be933 100644 --- a/pkg/util/limit/limiter_test.go +++ b/pkg/util/limit/limiter_test.go @@ -17,6 +17,7 @@ import ( "testing" "github.com/cockroachdb/cockroach/pkg/util/leaktest" + "github.com/cockroachdb/errors" "golang.org/x/sync/errgroup" ) @@ -40,7 +41,7 @@ func TestConcurrentRequestLimiter(t *testing.T) { for { //t.Logf("waiting to make request %d... (%d / %d)", req+1, l.sem.GetCount(), l.sem.GetLimit()) if err := l.Begin(ctx); err != nil { - if err == ctx.Err() { + if errors.Is(err, ctx.Err()) { break } else { return err diff --git a/pkg/util/quotapool/intpool.go b/pkg/util/quotapool/intpool.go index 8f32339c2592..8e5c90b5d2ca 100644 --- a/pkg/util/quotapool/intpool.go +++ b/pkg/util/quotapool/intpool.go @@ -499,7 +499,7 @@ func (r *intFuncRequest) Acquire(ctx context.Context, v Resource) (fulfilled boo if took != 0 { panic(fmt.Sprintf("IntRequestFunc returned both took: %d and err: %s", took, err)) } - if err == ErrNotEnoughQuota { + if errors.Is(err, ErrNotEnoughQuota) { return false, nil } r.err = err diff --git a/pkg/util/quotapool/intpool_test.go b/pkg/util/quotapool/intpool_test.go index 06f665751f02..2e03bbcfcf37 100644 --- a/pkg/util/quotapool/intpool_test.go +++ b/pkg/util/quotapool/intpool_test.go @@ -103,7 +103,7 @@ func TestQuotaPoolContextCancellation(t *testing.T) { case <-time.After(5 * time.Second): t.Fatal("context cancellation did not unblock acquisitions within 5s") case err := <-errCh: - if err != context.Canceled { + if !errors.Is(err, context.Canceled) { t.Fatalf("expected context cancellation error, got %v", err) } } @@ -194,7 +194,7 @@ func TestQuotaPoolCanceledAcquisitions(t *testing.T) { case <-time.After(5 * time.Second): t.Fatal("context cancellations did not unblock acquisitions within 5s") case err := <-errCh: - if err != context.Canceled { + if !errors.Is(err, context.Canceled) { t.Fatalf("expected context cancellation error, got %v", err) } } diff --git a/pkg/util/stop/stopper.go b/pkg/util/stop/stopper.go index c6f587f33d8d..72924de463d8 100644 --- a/pkg/util/stop/stopper.go +++ b/pkg/util/stop/stopper.go @@ -345,7 +345,7 @@ func (s *Stopper) RunLimitedAsyncTask( } else { alloc, err = sem.TryAcquire(ctx, 1) } - if err == quotapool.ErrNotEnoughQuota { + if errors.Is(err, quotapool.ErrNotEnoughQuota) { err = ErrThrottled } else if quotapool.HasErrClosed(err) { err = ErrUnavailable diff --git a/pkg/util/stop/stopper_test.go b/pkg/util/stop/stopper_test.go index a90b65ed17b2..bb33128cd57b 100644 --- a/pkg/util/stop/stopper_test.go +++ b/pkg/util/stop/stopper_test.go @@ -407,15 +407,15 @@ func TestStopperWithCancel(t *testing.T) { if err := ctx2.Err(); err != nil { t.Fatalf("should not be canceled: %v", err) } - if err := ctx3.Err(); err != context.Canceled { + if err := ctx3.Err(); !errors.Is(err, context.Canceled) { t.Fatalf("should be canceled: %v", err) } - if err := ctx4.Err(); err != context.Canceled { + if err := ctx4.Err(); !errors.Is(err, context.Canceled) { t.Fatalf("should be canceled: %v", err) } s.Quiesce(ctx) - if err := ctx1.Err(); err != context.Canceled { + if err := ctx1.Err(); !errors.Is(err, context.Canceled) { t.Fatalf("should be canceled: %v", err) } if err := ctx2.Err(); err != nil { @@ -423,7 +423,7 @@ func TestStopperWithCancel(t *testing.T) { } s.Stop(ctx) - if err := ctx2.Err(); err != context.Canceled { + if err := ctx2.Err(); !errors.Is(err, context.Canceled) { t.Fatalf("should be canceled: %v", err) } } @@ -457,10 +457,10 @@ func TestStopperWithCancelConcurrent(t *testing.T) { }() wg.Wait() - if err := ctx1.Err(); err != context.Canceled { + if err := ctx1.Err(); !errors.Is(err, context.Canceled) { t.Errorf("should be canceled: %v", err) } - if err := ctx2.Err(); err != context.Canceled { + if err := ctx2.Err(); !errors.Is(err, context.Canceled) { t.Errorf("should be canceled: %v", err) } } @@ -598,7 +598,7 @@ func TestStopperRunLimitedAsyncTask(t *testing.T) { context.Background(), "test", sem, false /* wait */, func(_ context.Context) { }, ) - if err != stop.ErrThrottled { + if !errors.Is(err, stop.ErrThrottled) { t.Fatalf("expected %v; got %v", stop.ErrThrottled, err) } } @@ -652,7 +652,7 @@ func TestStopperRunLimitedAsyncTaskCancelContext(t *testing.T) { if err := s.RunAsyncTask(ctx, "test", func(ctx context.Context) { for i := 0; i < maxConcurrency*2; i++ { if err := s.RunLimitedAsyncTask(ctx, "test", sem, true, f); err != nil { - if err != context.Canceled { + if !errors.Is(err, context.Canceled) { t.Fatal(err) } atomic.AddInt32(&workersCanceled, 1) diff --git a/pkg/util/syncutil/singleflight/singleflight_test.go b/pkg/util/syncutil/singleflight/singleflight_test.go index 90af13a6eb26..d677b76deefa 100644 --- a/pkg/util/syncutil/singleflight/singleflight_test.go +++ b/pkg/util/syncutil/singleflight/singleflight_test.go @@ -53,7 +53,7 @@ func TestDoErr(t *testing.T) { v, _, err := g.Do("key", func() (interface{}, error) { return nil, someErr }) - if err != someErr { + if !errors.Is(err, someErr) { t.Errorf("Do error = %v; want someErr %v", err, someErr) } if v != nil { diff --git a/pkg/util/uuid/uuid_test.go b/pkg/util/uuid/uuid_test.go index 48d12001f0d5..4853e4135273 100644 --- a/pkg/util/uuid/uuid_test.go +++ b/pkg/util/uuid/uuid_test.go @@ -22,6 +22,8 @@ import ( "math" "testing" "time" + + "github.com/cockroachdb/errors" ) func TestUUID(t *testing.T) { @@ -121,7 +123,7 @@ func TestMust(t *testing.T) { if !ok { t.Fatalf("panicked with %T, want error (%v)", r, sentinel) } - if err != sentinel { + if !errors.Is(err, sentinel) { t.Fatalf("panicked with %v, want %v", err, sentinel) } }() diff --git a/pkg/workload/cli/run.go b/pkg/workload/cli/run.go index 701ca3225bfe..806a6681643b 100644 --- a/pkg/workload/cli/run.go +++ b/pkg/workload/cli/run.go @@ -231,7 +231,7 @@ func workerRun( } if err := workFn(ctx); err != nil { - if errors.Cause(err) == ctx.Err() { + if errors.Is(err, ctx.Err()) { return } errCh <- err diff --git a/pkg/workload/interleavedpartitioned/interleavedpartitioned.go b/pkg/workload/interleavedpartitioned/interleavedpartitioned.go index ad0bde3dff6a..9224dcf00f26 100644 --- a/pkg/workload/interleavedpartitioned/interleavedpartitioned.go +++ b/pkg/workload/interleavedpartitioned/interleavedpartitioned.go @@ -664,12 +664,12 @@ func (w *interleavedPartitioned) fetchSessionID( start := timeutil.Now() baseSessionID := randomSessionID(rng, locality, localPercent) var sessionID string - if err := w.findSessionIDStatement1.QueryRowContext(ctx, baseSessionID).Scan(&sessionID); err != nil && err != gosql.ErrNoRows { + if err := w.findSessionIDStatement1.QueryRowContext(ctx, baseSessionID).Scan(&sessionID); err != nil && !errors.Is(err, gosql.ErrNoRows) { return "", err } // Didn't find a next session ID, let's try the other way. if len(sessionID) == 0 { - if err := w.findSessionIDStatement2.QueryRowContext(ctx, baseSessionID).Scan(&sessionID); err != nil && err != gosql.ErrNoRows { + if err := w.findSessionIDStatement2.QueryRowContext(ctx, baseSessionID).Scan(&sessionID); err != nil && !errors.Is(err, gosql.ErrNoRows) { return "", err } } diff --git a/pkg/workload/schemachange/schemachange.go b/pkg/workload/schemachange/schemachange.go index e5d8e3ce8f7a..143d79047d06 100644 --- a/pkg/workload/schemachange/schemachange.go +++ b/pkg/workload/schemachange/schemachange.go @@ -390,7 +390,7 @@ func (w *schemaChangeWorker) randOp(tx *pgx.Tx) (string, string, error) { } // TODO(spaskob): use more fine-grained error reporting. - if stmt == "" || err == pgx.ErrNoRows { + if stmt == "" || errors.Is(err, pgx.ErrNoRows) { if w.verbose >= 2 { log.WriteString(fmt.Sprintf("NOOP: %s -> %v\n", op, err)) } diff --git a/pkg/workload/tpcc/delivery.go b/pkg/workload/tpcc/delivery.go index 21325b39b2f9..127b2dcb7bec 100644 --- a/pkg/workload/tpcc/delivery.go +++ b/pkg/workload/tpcc/delivery.go @@ -100,7 +100,7 @@ func (del *delivery) run(ctx context.Context, wID int) (interface{}, error) { var oID int if err := del.selectNewOrder.QueryRowTx(ctx, tx, wID, dID).Scan(&oID); err != nil { // If no matching order is found, the delivery of this order is skipped. - if err != gosql.ErrNoRows { + if !errors.Is(err, gosql.ErrNoRows) { atomic.AddUint64(&del.config.auditor.skippedDelivieries, 1) return err } diff --git a/pkg/workload/tpcc/new_order.go b/pkg/workload/tpcc/new_order.go index 46f81d5a3de7..55df81018f50 100644 --- a/pkg/workload/tpcc/new_order.go +++ b/pkg/workload/tpcc/new_order.go @@ -433,7 +433,7 @@ func (n *newOrder) run(ctx context.Context, wID int) (interface{}, error) { return nil }) - if err == errSimulated { + if errors.Is(err, errSimulated) { return d, nil } return d, err diff --git a/pkg/workload/ycsb/ycsb.go b/pkg/workload/ycsb/ycsb.go index a53254f94d5a..719841b30880 100644 --- a/pkg/workload/ycsb/ycsb.go +++ b/pkg/workload/ycsb/ycsb.go @@ -716,7 +716,7 @@ func (yw *ycsbWorker) readModifyWriteRow(ctx context.Context) error { _, err := tx.StmtContext(ctx, updateStmt).ExecContext(ctx, args[:]...) return err }) - if err == gosql.ErrNoRows && ctx.Err() != nil { + if errors.Is(err, gosql.ErrNoRows) && ctx.Err() != nil { // Sometimes a context cancellation during a transaction can result in // sql.ErrNoRows instead of the appropriate context.DeadlineExceeded. In // this case, we just return ctx.Err(). See