Skip to content

Commit

Permalink
GODRIVER-1706 Ensure codeName is propagated for errors (#458)
Browse files Browse the repository at this point in the history
  • Loading branch information
Divjot Arora committed Aug 3, 2020
1 parent 61c3712 commit de7fae1
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 6 deletions.
7 changes: 6 additions & 1 deletion mongo/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,12 @@ func convertDriverWriteConcernError(wce *driver.WriteConcernError) *WriteConcern
return nil
}

return &WriteConcernError{Code: int(wce.Code), Message: wce.Message, Details: bson.Raw(wce.Details)}
return &WriteConcernError{
Name: wce.Name,
Code: int(wce.Code),
Message: wce.Message,
Details: bson.Raw(wce.Details),
}
}

// BulkWriteError is an error that occurred during execution of one operation in a BulkWrite. This error type is only
Expand Down
12 changes: 7 additions & 5 deletions mongo/integration/collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@ const (
errorModifiedID = 66
)

func TestCollection(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().CreateClient(false))
defer mt.Close()

var (
// impossibleWc is a write concern that can't be satisfied and is used to test write concern errors
// for various operations. It includes a timeout because legacy servers will wait for all W nodes to respond,
// causing tests to hang.
impossibleWc := writeconcern.New(writeconcern.W(30), writeconcern.WTimeout(time.Second))
impossibleWc = writeconcern.New(writeconcern.W(30), writeconcern.WTimeout(time.Second))
)

func TestCollection(t *testing.T) {
mt := mtest.New(t, mtest.NewOptions().CreateClient(false))
defer mt.Close()

mt.RunOpts("insert one", noClientOpts, func(mt *mtest.T) {
mt.Run("success", func(mt *mtest.T) {
Expand Down
49 changes: 49 additions & 0 deletions mongo/integration/crud_prose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,52 @@ func TestAggregateSecondaryPreferredReadPreference(t *testing.T) {
assert.NotNil(mt, err, "expected command %s to not contain $readPreference", evt.Command)
})
}

func TestErrorsCodeNamePropagated(t *testing.T) {
// Ensure the codeName field is propagated for both command and write concern errors.

mtOpts := mtest.NewOptions().
Topologies(mtest.ReplicaSet).
CreateClient(false)
mt := mtest.New(t, mtOpts)
defer mt.Close()

mt.RunOpts("command error", mtest.NewOptions().MinServerVersion("3.4"), func(mt *mtest.T) {
// codeName is propagated in an ok:0 error.

cmd := bson.D{
{"insert", mt.Coll.Name()},
{"documents", []bson.D{}},
}
err := mt.DB.RunCommand(mtest.Background, cmd).Err()
assert.NotNil(mt, err, "expected RunCommand error, got nil")

ce, ok := err.(mongo.CommandError)
assert.True(mt, ok, "expected error of type %T, got %v of type %T", mongo.CommandError{}, err, err)
expectedCodeName := "InvalidLength"
assert.Equal(mt, expectedCodeName, ce.Name, "expected error code name %q, got %q", expectedCodeName, ce.Name)
})

wcCollOpts := options.Collection().
SetWriteConcern(impossibleWc)
wcMtOpts := mtest.NewOptions().
CollectionOptions(wcCollOpts)
mt.RunOpts("write concern error", wcMtOpts, func(mt *mtest.T) {
// codeName is propagated for write concern errors.

_, err := mt.Coll.InsertOne(mtest.Background, bson.D{})
assert.NotNil(mt, err, "expected InsertOne error, got nil")

we, ok := err.(mongo.WriteException)
assert.True(mt, ok, "expected error of type %T, got %v of type %T", mongo.WriteException{}, err, err)
wce := we.WriteConcernError
assert.NotNil(mt, wce, "expected write concern error, got %v", we)

var expectedCodeName string
if codeNameVal, err := mt.GetSucceededEvent().Reply.LookupErr("writeConcernError", "codeName"); err == nil {
expectedCodeName = codeNameVal.StringValue()
}

assert.Equal(mt, expectedCodeName, wce.Name, "expected code name %q, got %q", expectedCodeName, wce.Name)
})
}

0 comments on commit de7fae1

Please sign in to comment.