@@ -23,6 +23,36 @@ import (
23
23
"go.mongodb.org/mongo-driver/mongo/options"
24
24
)
25
25
26
+ type netErr struct {
27
+ timeout bool
28
+ }
29
+
30
+ func (n netErr ) Error () string {
31
+ return "error"
32
+ }
33
+
34
+ func (n netErr ) Timeout () bool {
35
+ return n .timeout
36
+ }
37
+
38
+ func (n netErr ) Temporary () bool {
39
+ return false
40
+ }
41
+
42
+ var _ net.Error = (* netErr )(nil )
43
+
44
+ type wrappedError struct {
45
+ err error
46
+ }
47
+
48
+ func (we wrappedError ) Error () string {
49
+ return we .err .Error ()
50
+ }
51
+
52
+ func (we wrappedError ) Unwrap () error {
53
+ return we .err
54
+ }
55
+
26
56
func TestErrors (t * testing.T ) {
27
57
mt := mtest .New (t , noClientOpts )
28
58
defer mt .Close ()
@@ -289,4 +319,124 @@ func TestErrors(t *testing.T) {
289
319
})
290
320
}
291
321
})
322
+ mt .Run ("error helpers" , func (mt * mtest.T ) {
323
+ //IsDuplicateKeyError
324
+ mt .Run ("IsDuplicateKeyError" , func (mt * mtest.T ) {
325
+ testCases := []struct {
326
+ name string
327
+ err error
328
+ result bool
329
+ }{
330
+ {"CommandError true" , mongo.CommandError {11000 , "" , nil , "blah" , nil }, true },
331
+ {"CommandError false" , mongo.CommandError {100 , "" , nil , "blah" , nil }, false },
332
+ {
333
+ "WriteException true in writeConcernError" ,
334
+ mongo.WriteException {
335
+ & mongo.WriteConcernError {"name" , 11001 , "bar" , nil },
336
+ mongo.WriteErrors {
337
+ mongo.WriteError {0 , 100 , "baz" },
338
+ },
339
+ nil ,
340
+ },
341
+ true ,
342
+ },
343
+ {
344
+ "WriteException true in writeErrors" ,
345
+ mongo.WriteException {
346
+ & mongo.WriteConcernError {"name" , 100 , "bar" , nil },
347
+ mongo.WriteErrors {
348
+ mongo.WriteError {0 , 12582 , "baz" },
349
+ },
350
+ nil ,
351
+ },
352
+ true ,
353
+ },
354
+ {
355
+ "WriteException false" ,
356
+ mongo.WriteException {
357
+ & mongo.WriteConcernError {"name" , 16460 , "bar" , nil },
358
+ mongo.WriteErrors {
359
+ mongo.WriteError {0 , 100 , "blah E11000 blah" },
360
+ },
361
+ nil ,
362
+ },
363
+ false ,
364
+ },
365
+ {
366
+ "BulkWriteException true" ,
367
+ mongo.BulkWriteException {
368
+ & mongo.WriteConcernError {"name" , 100 , "bar" , nil },
369
+ []mongo.BulkWriteError {
370
+ {mongo.WriteError {0 , 16460 , "blah E11000 blah" }, & mongo.InsertOneModel {}},
371
+ },
372
+ []string {"otherError" },
373
+ },
374
+ true ,
375
+ },
376
+ {
377
+ "BulkWriteException false" ,
378
+ mongo.BulkWriteException {
379
+ & mongo.WriteConcernError {"name" , 100 , "bar" , nil },
380
+ []mongo.BulkWriteError {
381
+ {mongo.WriteError {0 , 110 , "blah" }, & mongo.InsertOneModel {}},
382
+ },
383
+ []string {"otherError" },
384
+ },
385
+ false ,
386
+ },
387
+ {"wrapped error" , wrappedError {mongo.CommandError {11000 , "" , nil , "blah" , nil }}, true },
388
+ {"other error type" , errors .New ("foo" ), false },
389
+ }
390
+ for _ , tc := range testCases {
391
+ mt .Run (tc .name , func (mt * mtest.T ) {
392
+ res := mongo .IsDuplicateKeyError (tc .err )
393
+ assert .Equal (mt , res , tc .result , "expected IsDuplicateKeyError %v, got %v" , tc .result , res )
394
+ })
395
+ }
396
+ })
397
+ //IsNetworkError
398
+ mt .Run ("IsNetworkError" , func (mt * mtest.T ) {
399
+ const networkLabel = "NetworkError"
400
+ const otherLabel = "other"
401
+ testCases := []struct {
402
+ name string
403
+ err error
404
+ result bool
405
+ }{
406
+ {"ServerError true" , mongo.CommandError {100 , "" , []string {networkLabel }, "blah" , nil }, true },
407
+ {"ServerError false" , mongo.CommandError {100 , "" , []string {otherLabel }, "blah" , nil }, false },
408
+ {"wrapped error" , wrappedError {mongo.CommandError {100 , "" , []string {networkLabel }, "blah" , nil }}, true },
409
+ {"other error type" , errors .New ("foo" ), false },
410
+ }
411
+ for _ , tc := range testCases {
412
+ mt .Run (tc .name , func (mt * mtest.T ) {
413
+ res := mongo .IsNetworkError (tc .err )
414
+ assert .Equal (mt , res , tc .result , "expected IsNetworkError %v, got %v" , tc .result , res )
415
+ })
416
+ }
417
+ })
418
+ //IsTimeout
419
+ mt .Run ("IsTimeout" , func (mt * mtest.T ) {
420
+ testCases := []struct {
421
+ name string
422
+ err error
423
+ result bool
424
+ }{
425
+ {"context timeout" , mongo.CommandError {100 , "" , []string {"other" }, "blah" , context .DeadlineExceeded }, true },
426
+ {"ServerError NetworkTimeoutError" , mongo.CommandError {100 , "" , []string {"NetworkTimeoutError" }, "blah" , nil }, true },
427
+ {"ServerError ExceededTimeLimitError" , mongo.CommandError {100 , "" , []string {"ExceededTimeLimitError" }, "blah" , nil }, true },
428
+ {"ServerError false" , mongo.CommandError {100 , "" , []string {"other" }, "blah" , nil }, false },
429
+ {"net error true" , mongo.CommandError {100 , "" , []string {"other" }, "blah" , netErr {true }}, true },
430
+ {"net error false" , netErr {false }, false },
431
+ {"wrapped error" , wrappedError {mongo.CommandError {100 , "" , []string {"other" }, "blah" , context .DeadlineExceeded }}, true },
432
+ {"other error" , errors .New ("foo" ), false },
433
+ }
434
+ for _ , tc := range testCases {
435
+ mt .Run (tc .name , func (mt * mtest.T ) {
436
+ res := mongo .IsTimeout (tc .err )
437
+ assert .Equal (mt , res , tc .result , "expected IsTimeout %v, got %v" , tc .result , res )
438
+ })
439
+ }
440
+ })
441
+ })
292
442
}
0 commit comments