Skip to content

Commit 0f35742

Browse files
author
Isabella Siu
committed
GODRIVER-400 return multiple errors for write operations
Change-Id: Id66a0df9b6865fc1d90fe667490ce4aae5705a42
1 parent 0cb0bd0 commit 0f35742

File tree

2 files changed

+86
-52
lines changed

2 files changed

+86
-52
lines changed

mongo/collection_internal_test.go

Lines changed: 67 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -288,16 +288,16 @@ func TestCollection_InsertOne_WriteError(t *testing.T) {
288288
_, err := coll.InsertOne(context.Background(), doc)
289289
require.NoError(t, err)
290290
_, err = coll.InsertOne(context.Background(), doc)
291-
got, ok := err.(WriteErrors)
291+
got, ok := err.(WriteException)
292292
if !ok {
293-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteErrors{})
293+
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteException{})
294294
}
295-
if len(got) != 1 {
296-
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got), 1)
295+
if len(got.WriteErrors) != 1 {
296+
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got.WriteErrors), 1)
297297
t.FailNow()
298298
}
299-
if got[0].Code != want.Code {
300-
t.Errorf("Did not receive the correct error code. got %d; want %d", got[0].Code, want.Code)
299+
if got.WriteErrors[0].Code != want.Code {
300+
t.Errorf("Did not receive the correct error code. got %d; want %d", got.WriteErrors[0].Code, want.Code)
301301
}
302302

303303
}
@@ -315,8 +315,12 @@ func TestCollection_InsertOne_WriteConcernError(t *testing.T) {
315315
coll := createTestCollection(t, nil, nil, options.Collection().SetWriteConcern(impossibleWriteConcern))
316316

317317
_, err := coll.InsertOne(context.Background(), doc)
318-
if _, ok := err.(WriteConcernError); !ok {
319-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteConcernError{})
318+
writeErr, ok := err.(WriteException)
319+
if !ok {
320+
t.Errorf("incorrect error type returned: %T", writeErr)
321+
}
322+
if writeErr.WriteConcernError == nil {
323+
t.Errorf("write concern error is nil: %+v", writeErr)
320324
}
321325
}
322326

@@ -661,17 +665,17 @@ func TestCollection_DeleteOne_WriteError(t *testing.T) {
661665
coll := db.Collection(testutil.ColName(t))
662666

663667
_, err = coll.DeleteOne(context.Background(), filter)
664-
got, ok := err.(WriteErrors)
668+
got, ok := err.(WriteException)
665669
if !ok {
666-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteErrors{})
670+
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteException{})
667671
}
668-
if len(got) != 1 {
669-
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got), 1)
672+
if len(got.WriteErrors) != 1 {
673+
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got.WriteErrors), 1)
670674
t.FailNow()
671675
}
672676
// 2.6 returns 10101 instead of 20
673-
if got[0].Code != 20 && got[0].Code != 10101 {
674-
t.Errorf("Did not receive the correct error code. got %d; want 20 or 10101", got[0].Code)
677+
if got.WriteErrors[0].Code != 20 && got.WriteErrors[0].Code != 10101 {
678+
t.Errorf("Did not receive the correct error code. got %d; want 20 or 10101", got.WriteErrors[0].Code)
675679
}
676680
}
677681

@@ -698,9 +702,12 @@ func TestCollection_DeleteMany_WriteConcernError(t *testing.T) {
698702
t.Fatalf("error cloning collection: %s", err)
699703
}
700704
_, err = cloned.DeleteOne(context.Background(), filter)
701-
_, ok := err.(WriteConcernError)
705+
writeErr, ok := err.(WriteException)
702706
if !ok {
703-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteConcernError{})
707+
t.Errorf("incorrect error type returned: %T", writeErr)
708+
}
709+
if writeErr.WriteConcernError == nil {
710+
t.Errorf("write concern error is nil: %+v", writeErr)
704711
}
705712
}
706713

@@ -773,17 +780,17 @@ func TestCollection_DeleteMany_WriteError(t *testing.T) {
773780
coll := db.Collection(testutil.ColName(t))
774781

775782
_, err = coll.DeleteMany(context.Background(), filter)
776-
got, ok := err.(WriteErrors)
783+
got, ok := err.(WriteException)
777784
if !ok {
778-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteErrors{})
785+
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteException{})
779786
}
780-
if len(got) != 1 {
781-
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got), 1)
787+
if len(got.WriteErrors) != 1 {
788+
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got.WriteErrors), 1)
782789
t.FailNow()
783790
}
784791
// 2.6 returns 10101 instead of 20
785-
if got[0].Code != 20 && got[0].Code != 10101 {
786-
t.Errorf("Did not receive the correct error code. got %d; want 20 or 10101", got[0].Code)
792+
if got.WriteErrors[0].Code != 20 && got.WriteErrors[0].Code != 10101 {
793+
t.Errorf("Did not receive the correct error code. got %d; want 20 or 10101", got.WriteErrors[0].Code)
787794
}
788795
}
789796

@@ -811,9 +818,12 @@ func TestCollection_DeleteOne_WriteConcernError(t *testing.T) {
811818
}
812819

813820
_, err = cloned.DeleteMany(context.Background(), filter)
814-
_, ok := err.(WriteConcernError)
821+
writeErr, ok := err.(WriteException)
815822
if !ok {
816-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteConcernError{})
823+
t.Errorf("incorrect error type returned: %T", writeErr)
824+
}
825+
if writeErr.WriteConcernError == nil {
826+
t.Errorf("write concern error is nil: %+v", writeErr)
817827
}
818828
}
819829

@@ -895,16 +905,16 @@ func TestCollection_UpdateOne_WriteError(t *testing.T) {
895905
require.NoError(t, err)
896906

897907
_, err = coll.UpdateOne(context.Background(), filter, update)
898-
got, ok := err.(WriteErrors)
908+
got, ok := err.(WriteException)
899909
if !ok {
900-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteErrors{})
910+
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteException{})
901911
}
902-
if len(got) != 1 {
903-
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got), 1)
912+
if len(got.WriteErrors) != 1 {
913+
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got.WriteErrors), 1)
904914
t.FailNow()
905915
}
906-
if got[0].Code != want.Code {
907-
t.Errorf("Did not receive the correct error code. got %d; want %d", got[0].Code, want.Code)
916+
if got.WriteErrors[0].Code != want.Code {
917+
t.Errorf("Did not receive the correct error code. got %d; want %d", got.WriteErrors[0].Code, want.Code)
908918
}
909919

910920
}
@@ -933,9 +943,12 @@ func TestCollection_UpdateOne_WriteConcernError(t *testing.T) {
933943
t.Fatalf("error cloning collection: %s", err)
934944
}
935945
_, err = cloned.UpdateOne(context.Background(), filter, update)
936-
_, ok := err.(WriteConcernError)
946+
writeErr, ok := err.(WriteException)
937947
if !ok {
938-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteConcernError{})
948+
t.Errorf("incorrect error type returned: %T", writeErr)
949+
}
950+
if writeErr.WriteConcernError == nil {
951+
t.Errorf("write concern error is nil: %+v", writeErr)
939952
}
940953
}
941954

@@ -1019,16 +1032,16 @@ func TestCollection_UpdateMany_WriteError(t *testing.T) {
10191032
require.NoError(t, err)
10201033

10211034
_, err = coll.UpdateMany(context.Background(), filter, update)
1022-
got, ok := err.(WriteErrors)
1035+
got, ok := err.(WriteException)
10231036
if !ok {
1024-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteErrors{})
1037+
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteException{})
10251038
}
1026-
if len(got) != 1 {
1027-
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got), 1)
1039+
if len(got.WriteErrors) != 1 {
1040+
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got.WriteErrors), 1)
10281041
t.FailNow()
10291042
}
1030-
if got[0].Code != want.Code {
1031-
t.Errorf("Did not receive the correct error code. got %d; want %d", got[0].Code, want.Code)
1043+
if got.WriteErrors[0].Code != want.Code {
1044+
t.Errorf("Did not receive the correct error code. got %d; want %d", got.WriteErrors[0].Code, want.Code)
10321045
}
10331046

10341047
}
@@ -1057,9 +1070,12 @@ func TestCollection_UpdateMany_WriteConcernError(t *testing.T) {
10571070
t.Fatalf("error cloning collection: %s", err)
10581071
}
10591072
_, err = cloned.UpdateMany(context.Background(), filter, update)
1060-
_, ok := err.(WriteConcernError)
1073+
writeErr, ok := err.(WriteException)
10611074
if !ok {
1062-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteConcernError{})
1075+
t.Errorf("incorrect error type returned: %T", writeErr)
1076+
}
1077+
if writeErr.WriteConcernError == nil {
1078+
t.Errorf("write concern error is nil: %+v", writeErr)
10631079
}
10641080
}
10651081

@@ -1134,19 +1150,19 @@ func TestCollection_ReplaceOne_WriteError(t *testing.T) {
11341150
require.NoError(t, err)
11351151

11361152
_, err = coll.ReplaceOne(context.Background(), filter, replacement)
1137-
got, ok := err.(WriteErrors)
1153+
got, ok := err.(WriteException)
11381154
if !ok {
1139-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteErrors{})
1155+
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteException{})
11401156
}
1141-
if len(got) != 1 {
1142-
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got), 1)
1157+
if len(got.WriteErrors) != 1 {
1158+
t.Errorf("Incorrect number of errors receieved. got %d; want %d", len(got.WriteErrors), 1)
11431159
t.FailNow()
11441160
}
1145-
switch got[0].Code {
1161+
switch got.WriteErrors[0].Code {
11461162
case 66: // mongod v3.6
11471163
case 16837: //mongod v3.4, mongod v3.2
11481164
default:
1149-
t.Errorf("Did not receive the correct error code. got %d; want (one of) %d", got[0].Code, []int{66, 16837})
1165+
t.Errorf("Did not receive the correct error code. got %d; want (one of) %d", got.WriteErrors[0].Code, []int{66, 16837})
11501166
fmt.Printf("%#v\n", got)
11511167
}
11521168

@@ -1176,9 +1192,12 @@ func TestCollection_ReplaceOne_WriteConcernError(t *testing.T) {
11761192
t.Fatalf("error cloning collection: %s", err)
11771193
}
11781194
_, err = cloned.ReplaceOne(context.Background(), filter, update)
1179-
_, ok := err.(WriteConcernError)
1195+
writeErr, ok := err.(WriteException)
11801196
if !ok {
1181-
t.Errorf("Did not receive correct type of error. got %T; want %T", err, WriteConcernError{})
1197+
t.Errorf("incorrect error type returned: %T", writeErr)
1198+
}
1199+
if writeErr.WriteConcernError == nil {
1200+
t.Errorf("write concern error is nil: %+v", writeErr)
11821201
}
11831202
}
11841203

mongo/errors.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,20 @@ type WriteConcernError struct {
8686

8787
func (wce WriteConcernError) Error() string { return wce.Message }
8888

89+
// WriteException is an error for a non-bulk write operation.
90+
type WriteException struct {
91+
WriteConcernError *WriteConcernError
92+
WriteErrors WriteErrors
93+
}
94+
95+
func (mwe WriteException) Error() string {
96+
var buf bytes.Buffer
97+
fmt.Fprint(&buf, "multiple write errors: [")
98+
fmt.Fprintf(&buf, "{%s}, ", mwe.WriteErrors)
99+
fmt.Fprintf(&buf, "{%s}]", mwe.WriteConcernError)
100+
return buf.String()
101+
}
102+
89103
func convertBulkWriteErrors(errors []driver.BulkWriteError) []BulkWriteError {
90104
bwErrors := make([]BulkWriteError, 0, len(errors))
91105
for _, err := range errors {
@@ -161,10 +175,11 @@ func processWriteError(wce *result.WriteConcernError, wes []result.WriteError, e
161175
return rrAll, ErrUnacknowledgedWrite
162176
case err != nil:
163177
return rrNone, replaceTopologyErr(err)
164-
case wce != nil:
165-
return rrMany, WriteConcernError{Code: wce.Code, Message: wce.ErrMsg}
166-
case len(wes) > 0:
167-
return rrMany, writeErrorsFromResult(wes)
178+
case wce != nil || len(wes) > 0:
179+
return rrMany, WriteException{
180+
WriteConcernError: convertWriteConcernError(wce),
181+
WriteErrors: writeErrorsFromResult(wes),
182+
}
168183
default:
169184
return rrAll, nil
170185
}

0 commit comments

Comments
 (0)