Skip to content

Commit 1720e22

Browse files
authored
GODRIVER-2531 Return canceled error message when canceled for waiting connection in wait queue. (#1058)
1 parent 4c8d1ad commit 1720e22

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

x/mongo/driver/topology/errors.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package topology
88

99
import (
10+
"context"
1011
"fmt"
1112

1213
"go.mongodb.org/mongo-driver/mongo/description"
@@ -78,8 +79,20 @@ type WaitQueueTimeoutError struct {
7879
// Error implements the error interface.
7980
func (w WaitQueueTimeoutError) Error() string {
8081
errorMsg := "timed out while checking out a connection from connection pool"
81-
if w.Wrapped != nil {
82-
errorMsg = fmt.Sprintf("%s: %s", errorMsg, w.Wrapped.Error())
82+
switch w.Wrapped {
83+
case nil:
84+
case context.Canceled:
85+
errorMsg = fmt.Sprintf(
86+
"%s: %s",
87+
"canceled while checking out a connection from connection pool",
88+
w.Wrapped.Error(),
89+
)
90+
default:
91+
errorMsg = fmt.Sprintf(
92+
"%s: %s",
93+
errorMsg,
94+
w.Wrapped.Error(),
95+
)
8396
}
8497

8598
return fmt.Sprintf(

x/mongo/driver/topology/pool_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ func TestPool(t *testing.T) {
645645
assert.IsTypef(t, WaitQueueTimeoutError{}, err, "expected a WaitQueueTimeoutError")
646646
if err, ok := err.(WaitQueueTimeoutError); ok {
647647
assert.Equalf(t, context.DeadlineExceeded, err.Unwrap(), "expected wrapped error to be a context.Timeout")
648+
assert.Containsf(t, err.Error(), "timed out", `expected error message to contain "timed out"`)
648649
}
649650

650651
p.close(context.Background())
@@ -773,6 +774,42 @@ func TestPool(t *testing.T) {
773774
assert.Equalf(t, 2, p.totalConnectionCount(), "pool should have 2 total connection")
774775
assert.Equalf(t, 0, p.availableConnectionCount(), "pool should have 0 idle connection")
775776

777+
p.close(context.Background())
778+
})
779+
t.Run("canceled context in wait queue", func(t *testing.T) {
780+
t.Parallel()
781+
782+
cleanup := make(chan struct{})
783+
defer close(cleanup)
784+
addr := bootstrapConnections(t, 1, func(nc net.Conn) {
785+
<-cleanup
786+
_ = nc.Close()
787+
})
788+
789+
p := newPool(poolConfig{
790+
Address: address.Address(addr.String()),
791+
MaxPoolSize: 1,
792+
})
793+
err := p.ready()
794+
noerr(t, err)
795+
796+
// Check out first connection.
797+
_, err = p.checkOut(context.Background())
798+
noerr(t, err)
799+
800+
// Use a canceled context to check out another connection.
801+
cancelCtx, cancel := context.WithCancel(context.Background())
802+
cancel()
803+
_, err = p.checkOut(cancelCtx)
804+
assert.NotNilf(t, err, "expected a non-nil error")
805+
806+
// Assert that error received is WaitQueueTimeoutError with context canceled.
807+
assert.IsTypef(t, WaitQueueTimeoutError{}, err, "expected a WaitQueueTimeoutError")
808+
if err, ok := err.(WaitQueueTimeoutError); ok {
809+
assert.Equalf(t, context.Canceled, err.Unwrap(), "expected wrapped error to be a context.Canceled")
810+
assert.Containsf(t, err.Error(), "canceled", `expected error message to contain "canceled"`)
811+
}
812+
776813
p.close(context.Background())
777814
})
778815
})

0 commit comments

Comments
 (0)