diff --git a/benchmark/harness_case.go b/benchmark/harness_case.go index fb2e0a0922..c55f943a04 100644 --- a/benchmark/harness_case.go +++ b/benchmark/harness_case.go @@ -8,6 +8,7 @@ package benchmark import ( "context" + "errors" "fmt" "path/filepath" "reflect" @@ -95,12 +96,12 @@ benchRepeat: res.Duration = c.elapsed c.cumulativeRuntime += res.Duration - switch res.Error { - case context.DeadlineExceeded: + switch { + case errors.Is(res.Error, context.DeadlineExceeded): break benchRepeat - case context.Canceled: + case errors.Is(res.Error, context.Canceled): break benchRepeat - case nil: + case res.Error == nil: out.Trials++ c.elapsed = 0 out.Raw = append(out.Raw, res) diff --git a/bson/bsoncodec/default_value_decoders.go b/bson/bsoncodec/default_value_decoders.go index 2ce119731b..4ba1b61019 100644 --- a/bson/bsoncodec/default_value_decoders.go +++ b/bson/bsoncodec/default_value_decoders.go @@ -41,7 +41,7 @@ func newDefaultStructCodec() *StructCodec { if err != nil { // This function is called from the codec registration path, so errors can't be propagated. If there's an error // constructing the StructCodec, we panic to avoid losing it. - panic(fmt.Errorf("error creating default StructCodec: %v", err)) + panic(fmt.Errorf("error creating default StructCodec: %w", err)) } return codec } @@ -178,7 +178,7 @@ func (dvd DefaultValueDecoders) DDecodeValue(dc DecodeContext, vr bsonrw.ValueRe for { key, elemVr, err := dr.ReadElement() - if err == bsonrw.ErrEOD { + if errors.Is(err, bsonrw.ErrEOD) { break } else if err != nil { return err @@ -1379,7 +1379,7 @@ func (dvd DefaultValueDecoders) MapDecodeValue(dc DecodeContext, vr bsonrw.Value keyType := val.Type().Key() for { key, vr, err := dr.ReadElement() - if err == bsonrw.ErrEOD { + if errors.Is(err, bsonrw.ErrEOD) { break } if err != nil { @@ -1675,7 +1675,7 @@ func (dvd DefaultValueDecoders) decodeDefault(dc DecodeContext, vr bsonrw.ValueR idx := 0 for { vr, err := ar.ReadValue() - if err == bsonrw.ErrEOA { + if errors.Is(err, bsonrw.ErrEOA) { break } if err != nil { diff --git a/bson/bsoncodec/default_value_decoders_test.go b/bson/bsoncodec/default_value_decoders_test.go index bac92e04f8..c3240d2f7f 100644 --- a/bson/bsoncodec/default_value_decoders_test.go +++ b/bson/bsoncodec/default_value_decoders_test.go @@ -2370,8 +2370,8 @@ func TestDefaultValueDecoders(t *testing.T) { return } if rc.val == cansettest { // We're doing an IsValid and CanSet test - wanterr, ok := rc.err.(ValueDecoderError) - if !ok { + var wanterr ValueDecoderError + if !errors.As(rc.err, &wanterr) { t.Fatalf("Error must be a DecodeValueError, but got a %T", rc.err) } @@ -3685,8 +3685,8 @@ func TestDefaultValueDecoders(t *testing.T) { val := reflect.New(reflect.TypeOf(outer{})).Elem() err := defaultTestStructCodec.DecodeValue(dc, vr, val) - decodeErr, ok := err.(*DecodeError) - assert.True(t, ok, "expected DecodeError, got %v of type %T", err, err) + var decodeErr *DecodeError + assert.True(t, errors.As(err, &decodeErr), "expected DecodeError, got %v of type %T", err, err) expectedKeys := []string{"foo", "bar"} assert.Equal(t, expectedKeys, decodeErr.Keys(), "expected keys slice %v, got %v", expectedKeys, decodeErr.Keys()) diff --git a/bson/bsoncodec/default_value_encoders.go b/bson/bsoncodec/default_value_encoders.go index 4ab14a668c..91a48c3a5b 100644 --- a/bson/bsoncodec/default_value_encoders.go +++ b/bson/bsoncodec/default_value_encoders.go @@ -343,7 +343,7 @@ func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.Docum } currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.MapIndex(key)) - if lookupErr != nil && lookupErr != errInvalidValue { + if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) { return lookupErr } @@ -418,7 +418,7 @@ func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.Val for idx := 0; idx < val.Len(); idx++ { currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx)) - if lookupErr != nil && lookupErr != errInvalidValue { + if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) { return lookupErr } @@ -487,7 +487,7 @@ func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.Val for idx := 0; idx < val.Len(); idx++ { currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx)) - if lookupErr != nil && lookupErr != errInvalidValue { + if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) { return lookupErr } diff --git a/bson/bsoncodec/map_codec.go b/bson/bsoncodec/map_codec.go index 325c1738ab..6a5292f2c0 100644 --- a/bson/bsoncodec/map_codec.go +++ b/bson/bsoncodec/map_codec.go @@ -313,7 +313,7 @@ func (mc *MapCodec) decodeKey(key string, keyType reflect.Type) (reflect.Value, if mc.EncodeKeysWithStringer { parsed, err := strconv.ParseFloat(key, 64) if err != nil { - return keyVal, fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %v", keyType.Kind(), err) + return keyVal, fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %w", keyType.Kind(), err) } keyVal = reflect.ValueOf(parsed) break diff --git a/bson/bsoncodec/struct_codec.go b/bson/bsoncodec/struct_codec.go index 4cde0a4d6b..d7d129d314 100644 --- a/bson/bsoncodec/struct_codec.go +++ b/bson/bsoncodec/struct_codec.go @@ -239,8 +239,8 @@ func (sc *StructCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val } func newDecodeError(key string, original error) error { - de, ok := original.(*DecodeError) - if !ok { + var de *DecodeError + if !errors.As(original, &de) { return &DecodeError{ keys: []string{key}, wrapped: original, diff --git a/bson/decoder_example_test.go b/bson/decoder_example_test.go index a59d995972..bcc6069c40 100644 --- a/bson/decoder_example_test.go +++ b/bson/decoder_example_test.go @@ -8,6 +8,7 @@ package bson_test import ( "bytes" + "errors" "fmt" "io" @@ -200,7 +201,7 @@ func ExampleDecoder_multipleExtendedJSONDocuments() { for { var res Coordinate err = decoder.Decode(&res) - if err == io.EOF { + if errors.Is(err, io.EOF) { break } if err != nil { diff --git a/bson/encoder_example_test.go b/bson/encoder_example_test.go index 054c6497ec..b52e999d45 100644 --- a/bson/encoder_example_test.go +++ b/bson/encoder_example_test.go @@ -8,6 +8,7 @@ package bson_test import ( "bytes" + "errors" "fmt" "io" @@ -162,7 +163,7 @@ func ExampleEncoder_multipleBSONDocuments() { // Extended JSON by converting them to bson.Raw. for { doc, err := bson.ReadDocument(buf) - if err == io.EOF { + if errors.Is(err, io.EOF) { return } if err != nil { diff --git a/bson/primitive/objectid.go b/bson/primitive/objectid.go index 9bbaffac26..c130e3ff19 100644 --- a/bson/primitive/objectid.go +++ b/bson/primitive/objectid.go @@ -183,7 +183,7 @@ func processUniqueBytes() [5]byte { var b [5]byte _, err := io.ReadFull(rand.Reader, b[:]) if err != nil { - panic(fmt.Errorf("cannot initialize objectid package with crypto.rand.Reader: %v", err)) + panic(fmt.Errorf("cannot initialize objectid package with crypto.rand.Reader: %w", err)) } return b @@ -193,7 +193,7 @@ func readRandomUint32() uint32 { var b [4]byte _, err := io.ReadFull(rand.Reader, b[:]) if err != nil { - panic(fmt.Errorf("cannot initialize objectid package with crypto.rand.Reader: %v", err)) + panic(fmt.Errorf("cannot initialize objectid package with crypto.rand.Reader: %w", err)) } return (uint32(b[0]) << 0) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24) diff --git a/cmd/testatlas/main.go b/cmd/testatlas/main.go index fa50d7cde7..ae1b15fcbc 100644 --- a/cmd/testatlas/main.go +++ b/cmd/testatlas/main.go @@ -8,6 +8,7 @@ package main import ( "context" + "errors" "flag" "fmt" "time" @@ -52,7 +53,7 @@ func main() { func runTest(ctx context.Context, clientOpts *options.ClientOptions) error { client, err := mongo.Connect(ctx, clientOpts) if err != nil { - return fmt.Errorf("Connect error: %v", err) + return fmt.Errorf("Connect error: %w", err) } defer func() { @@ -63,12 +64,12 @@ func runTest(ctx context.Context, clientOpts *options.ClientOptions) error { cmd := bson.D{{handshake.LegacyHello, 1}} err = db.RunCommand(ctx, cmd).Err() if err != nil { - return fmt.Errorf("legacy hello error: %v", err) + return fmt.Errorf("legacy hello error: %w", err) } coll := db.Collection("test") - if err = coll.FindOne(ctx, bson.D{{"x", 1}}).Err(); err != nil && err != mongo.ErrNoDocuments { - return fmt.Errorf("FindOne error: %v", err) + if err = coll.FindOne(ctx, bson.D{{"x", 1}}).Err(); err != nil && !errors.Is(err, mongo.ErrNoDocuments) { + return fmt.Errorf("FindOne error: %w", err) } return nil } diff --git a/cmd/testaws/main.go b/cmd/testaws/main.go index dc767e5add..ec4a1c91c3 100644 --- a/cmd/testaws/main.go +++ b/cmd/testaws/main.go @@ -8,6 +8,7 @@ package main import ( "context" + "errors" "fmt" "os" @@ -33,7 +34,7 @@ func main() { db := client.Database("aws") coll := db.Collection("test") - if err = coll.FindOne(ctx, bson.D{{"x", 1}}).Err(); err != nil && err != mongo.ErrNoDocuments { + if err = coll.FindOne(ctx, bson.D{{"x", 1}}).Err(); err != nil && !errors.Is(err, mongo.ErrNoDocuments) { panic(fmt.Sprintf("FindOne error: %v", err)) } } diff --git a/internal/aws/awserr/types.go b/internal/aws/awserr/types.go index 18cb4cda28..b70168f7d3 100644 --- a/internal/aws/awserr/types.go +++ b/internal/aws/awserr/types.go @@ -11,6 +11,7 @@ package awserr import ( + "errors" "fmt" ) @@ -106,7 +107,8 @@ func (b baseError) OrigErr() error { case 1: return b.errs[0] default: - if err, ok := b.errs[0].(Error); ok { + var err Error + if errors.As(b.errs[0], &err) { return NewBatchError(err.Code(), err.Message(), b.errs[1:]) } return NewBatchError("BatchedErrors", diff --git a/internal/csfle/csfle.go b/internal/csfle/csfle.go index 71e71b4687..20a6d43a0d 100644 --- a/internal/csfle/csfle.go +++ b/internal/csfle/csfle.go @@ -7,6 +7,7 @@ package csfle import ( + "errors" "fmt" "go.mongodb.org/mongo-driver/x/bsonx/bsoncore" @@ -23,7 +24,7 @@ func GetEncryptedStateCollectionName(efBSON bsoncore.Document, dataCollectionNam fieldName := stateCollection + "Collection" val, err := efBSON.LookupErr(fieldName) if err != nil { - if err != bsoncore.ErrElementNotFound { + if !errors.Is(err, bsoncore.ErrElementNotFound) { return "", err } // Return default name. diff --git a/mongo/cursor.go b/mongo/cursor.go index d2228ed9c4..c77d1109f4 100644 --- a/mongo/cursor.go +++ b/mongo/cursor.go @@ -160,13 +160,13 @@ func (c *Cursor) next(ctx context.Context, nonBlocking bool) bool { ctx = context.Background() } doc, err := c.batch.Next() - switch err { - case nil: + switch { + case err == nil: // Consume the next document in the current batch. c.batchLength-- c.Current = bson.Raw(doc) return true - case io.EOF: // Need to do a getMore + case errors.Is(err, io.EOF): // Need to do a getMore default: c.err = err return false @@ -204,12 +204,12 @@ func (c *Cursor) next(ctx context.Context, nonBlocking bool) bool { c.batch = c.bc.Batch() c.batchLength = c.batch.DocumentCount() doc, err = c.batch.Next() - switch err { - case nil: + switch { + case err == nil: c.batchLength-- c.Current = bson.Raw(doc) return true - case io.EOF: // Empty batch so we continue + case errors.Is(err, io.EOF): // Empty batch so we continue default: c.err = err return false diff --git a/mongo/integration/errors_test.go b/mongo/integration/errors_test.go index c74bc889c0..ad2da491aa 100644 --- a/mongo/integration/errors_test.go +++ b/mongo/integration/errors_test.go @@ -12,6 +12,7 @@ package integration import ( "context" "errors" + "fmt" "io" "net" "testing" @@ -45,18 +46,6 @@ func (n netErr) Temporary() bool { var _ net.Error = (*netErr)(nil) -type wrappedError struct { - err error -} - -func (we wrappedError) Error() string { - return we.err.Error() -} - -func (we wrappedError) Unwrap() error { - return we.err -} - func TestErrors(t *testing.T) { mt := mtest.New(t, noClientOpts) @@ -478,7 +467,7 @@ func TestErrors(t *testing.T) { }, false, }, - {"wrapped error", wrappedError{mongo.CommandError{11000, "", nil, "blah", nil, nil}}, true}, + {"wrapped error", fmt.Errorf("%w", mongo.CommandError{11000, "", nil, "blah", nil, nil}), true}, {"other error type", errors.New("foo"), false}, } for _, tc := range testCases { @@ -499,7 +488,7 @@ func TestErrors(t *testing.T) { }{ {"ServerError true", mongo.CommandError{100, "", []string{networkLabel}, "blah", nil, nil}, true}, {"ServerError false", mongo.CommandError{100, "", []string{otherLabel}, "blah", nil, nil}, false}, - {"wrapped error", wrappedError{mongo.CommandError{100, "", []string{networkLabel}, "blah", nil, nil}}, true}, + {"wrapped error", fmt.Errorf("%w", mongo.CommandError{100, "", []string{networkLabel}, "blah", nil, nil}), true}, {"other error type", errors.New("foo"), false}, } for _, tc := range testCases { @@ -533,8 +522,8 @@ func TestErrors(t *testing.T) { {"net error true", mongo.CommandError{ 100, "", []string{"other"}, "blah", netErr{true}, nil}, true}, {"net error false", netErr{false}, false}, - {"wrapped error", wrappedError{mongo.CommandError{ - 100, "", []string{"other"}, "blah", context.DeadlineExceeded, nil}}, true}, + {"wrapped error", fmt.Errorf("%w", mongo.CommandError{ + 100, "", []string{"other"}, "blah", context.DeadlineExceeded, nil}), true}, {"other error", errors.New("foo"), false}, } for _, tc := range testCases { diff --git a/mongo/integration/mtest/global_state.go b/mongo/integration/mtest/global_state.go index 4ca4219977..a8b15f47d8 100644 --- a/mongo/integration/mtest/global_state.go +++ b/mongo/integration/mtest/global_state.go @@ -79,7 +79,7 @@ func ServerVersion() string { func SetFailPoint(fp FailPoint, client *mongo.Client) error { admin := client.Database("admin") if err := admin.RunCommand(context.Background(), fp).Err(); err != nil { - return fmt.Errorf("error creating fail point: %v", err) + return fmt.Errorf("error creating fail point: %w", err) } return nil } @@ -89,7 +89,7 @@ func SetFailPoint(fp FailPoint, client *mongo.Client) error { func SetRawFailPoint(fp bson.Raw, client *mongo.Client) error { admin := client.Database("admin") if err := admin.RunCommand(context.Background(), fp).Err(); err != nil { - return fmt.Errorf("error creating fail point: %v", err) + return fmt.Errorf("error creating fail point: %w", err) } return nil } diff --git a/mongo/integration/mtest/mongotest.go b/mongo/integration/mtest/mongotest.go index 6e86583034..faf99e1259 100644 --- a/mongo/integration/mtest/mongotest.go +++ b/mongo/integration/mtest/mongotest.go @@ -8,6 +8,7 @@ package mtest import ( "context" + "errors" "fmt" "strings" "sync" @@ -463,11 +464,11 @@ func (t *T) CreateCollection(coll Collection, createOnServer bool) *mongo.Collec } // ignore ErrUnacknowledgedWrite. Client may be configured with unacknowledged write concern. - if err != nil && err != driver.ErrUnacknowledgedWrite { + if err != nil && !errors.Is(err, driver.ErrUnacknowledgedWrite) { // ignore NamespaceExists errors for idempotency - cmdErr, ok := err.(mongo.CommandError) - if !ok || cmdErr.Code != namespaceExistsErrCode { + var cmdErr mongo.CommandError + if !errors.As(err, &cmdErr) || cmdErr.Code != namespaceExistsErrCode { t.Fatalf("error creating collection or view: %v on server: %v", coll.Name, err) } } @@ -515,7 +516,7 @@ func (t *T) ClearCollections() { } err := coll.created.Drop(context.Background()) - if err == mongo.ErrUnacknowledgedWrite || err == driver.ErrUnacknowledgedWrite { + if errors.Is(err, mongo.ErrUnacknowledgedWrite) || errors.Is(err, driver.ErrUnacknowledgedWrite) { // It's possible that a collection could have an unacknowledged write concern, which // could prevent it from being dropped for sharded clusters. We can resolve this by // re-instantiating the collection with a majority write concern before dropping. diff --git a/mongo/integration/mtest/options.go b/mongo/integration/mtest/options.go index c756c414c5..0f103f7cd4 100644 --- a/mongo/integration/mtest/options.go +++ b/mongo/integration/mtest/options.go @@ -77,7 +77,7 @@ func (r *RunOnBlock) UnmarshalBSON(data []byte) error { Extra map[string]interface{} `bson:",inline"` } if err := bson.Unmarshal(data, &temp); err != nil { - return fmt.Errorf("error unmarshalling to temporary RunOnBlock object: %v", err) + return fmt.Errorf("error unmarshalling to temporary RunOnBlock object: %w", err) } if len(temp.Extra) > 0 { return fmt.Errorf("unrecognized fields for RunOnBlock: %v", temp.Extra) diff --git a/mongo/with_transactions_test.go b/mongo/with_transactions_test.go index 36b781383e..24a253059d 100644 --- a/mongo/with_transactions_test.go +++ b/mongo/with_transactions_test.go @@ -9,6 +9,7 @@ package mongo import ( "context" "errors" + "fmt" "math" "strconv" "strings" @@ -32,18 +33,6 @@ var ( errorInterrupted int32 = 11601 ) -type wrappedError struct { - err error -} - -func (we wrappedError) Error() string { - return we.err.Error() -} - -func (we wrappedError) Unwrap() error { - return we.err -} - func TestConvenientTransactions(t *testing.T) { if testing.Short() { t.Skip("skipping integration test in short mode") @@ -436,12 +425,12 @@ func TestConvenientTransactions(t *testing.T) { res, err := sess.WithTransaction(context.Background(), func(SessionContext) (interface{}, error) { if returnError { returnError = false - return nil, wrappedError{ + return nil, fmt.Errorf("%w", CommandError{ Name: "test Error", Labels: []string{driver.TransientTransactionError}, }, - } + ) } return false, nil }) diff --git a/x/mongo/driver/batch_cursor.go b/x/mongo/driver/batch_cursor.go index fefcfdb475..7d3703f7be 100644 --- a/x/mongo/driver/batch_cursor.go +++ b/x/mongo/driver/batch_cursor.go @@ -142,7 +142,7 @@ func NewCursorResponse(info ResponseInfo) (CursorResponse, error) { return CursorResponse{}, fmt.Errorf("expected Connection used to establish a cursor to implement PinnedConnection, but got %T", info.Connection) } if err := refConn.PinToCursor(); err != nil { - return CursorResponse{}, fmt.Errorf("error incrementing connection reference count when creating a cursor: %v", err) + return CursorResponse{}, fmt.Errorf("error incrementing connection reference count when creating a cursor: %w", err) } curresp.Connection = refConn } diff --git a/x/mongo/driver/connstring/connstring.go b/x/mongo/driver/connstring/connstring.go index cd43136471..b3dc97cf38 100644 --- a/x/mongo/driver/connstring/connstring.go +++ b/x/mongo/driver/connstring/connstring.go @@ -624,7 +624,8 @@ func (p *parser) addHost(host string) error { // this is unfortunate that SplitHostPort actually requires // a port to exist. if err != nil { - if addrError, ok := err.(*net.AddrError); !ok || addrError.Err != "missing port in address" { + var addrError *net.AddrError + if !errors.As(err, &addrError) || addrError.Err != "missing port in address" { return err } } diff --git a/x/mongo/driver/ocsp/config.go b/x/mongo/driver/ocsp/config.go index eac2aab7fa..94a5dd775f 100644 --- a/x/mongo/driver/ocsp/config.go +++ b/x/mongo/driver/ocsp/config.go @@ -57,7 +57,7 @@ func newConfig(certChain []*x509.Certificate, opts *VerifyOptions) (config, erro var err error cfg.ocspRequestBytes, err = ocsp.CreateRequest(cfg.serverCert, cfg.issuer, nil) if err != nil { - return cfg, fmt.Errorf("error creating OCSP request: %v", err) + return cfg, fmt.Errorf("error creating OCSP request: %w", err) } cfg.ocspRequest, err = ocsp.ParseRequest(cfg.ocspRequestBytes) if err != nil {