...
1
2
3
4
5
6
7 package topology
8
9 import (
10 "context"
11 "errors"
12 "fmt"
13 "time"
14
15 "go.mongodb.org/mongo-driver/mongo/description"
16 )
17
18
19 type ConnectionError struct {
20 ConnectionID string
21 Wrapped error
22
23
24
25 init bool
26 message string
27 }
28
29
30 func (e ConnectionError) Error() string {
31 message := e.message
32 if e.init {
33 fullMsg := "error occurred during connection handshake"
34 if message != "" {
35 fullMsg = fmt.Sprintf("%s: %s", fullMsg, message)
36 }
37 message = fullMsg
38 }
39 if e.Wrapped != nil && message != "" {
40 return fmt.Sprintf("connection(%s) %s: %s", e.ConnectionID, message, e.Wrapped.Error())
41 }
42 if e.Wrapped != nil {
43 return fmt.Sprintf("connection(%s) %s", e.ConnectionID, e.Wrapped.Error())
44 }
45 return fmt.Sprintf("connection(%s) %s", e.ConnectionID, message)
46 }
47
48
49 func (e ConnectionError) Unwrap() error {
50 return e.Wrapped
51 }
52
53
54 type ServerSelectionError struct {
55 Desc description.Topology
56 Wrapped error
57 }
58
59
60 func (e ServerSelectionError) Error() string {
61 if e.Wrapped != nil {
62 return fmt.Sprintf("server selection error: %s, current topology: { %s }", e.Wrapped.Error(), e.Desc.String())
63 }
64 return fmt.Sprintf("server selection error: current topology: { %s }", e.Desc.String())
65 }
66
67
68 func (e ServerSelectionError) Unwrap() error {
69 return e.Wrapped
70 }
71
72
73 type WaitQueueTimeoutError struct {
74 Wrapped error
75 pinnedConnections *pinnedConnections
76 maxPoolSize uint64
77 totalConnections int
78 availableConnections int
79 waitDuration time.Duration
80 }
81
82 type pinnedConnections struct {
83 cursorConnections uint64
84 transactionConnections uint64
85 }
86
87
88 func (w WaitQueueTimeoutError) Error() string {
89 errorMsg := "timed out while checking out a connection from connection pool"
90 switch {
91 case w.Wrapped == nil:
92 case errors.Is(w.Wrapped, context.Canceled):
93 errorMsg = fmt.Sprintf(
94 "%s: %s",
95 "canceled while checking out a connection from connection pool",
96 w.Wrapped.Error(),
97 )
98 default:
99 errorMsg = fmt.Sprintf(
100 "%s: %s",
101 errorMsg,
102 w.Wrapped.Error(),
103 )
104 }
105
106 msg := fmt.Sprintf("%s; total connections: %d, maxPoolSize: %d, ", errorMsg, w.totalConnections, w.maxPoolSize)
107 if pinnedConnections := w.pinnedConnections; pinnedConnections != nil {
108 openConnectionCount := uint64(w.totalConnections) -
109 pinnedConnections.cursorConnections -
110 pinnedConnections.transactionConnections
111 msg += fmt.Sprintf("connections in use by cursors: %d, connections in use by transactions: %d, connections in use by other operations: %d, ",
112 pinnedConnections.cursorConnections,
113 pinnedConnections.transactionConnections,
114 openConnectionCount,
115 )
116 }
117 msg += fmt.Sprintf("idle connections: %d, wait duration: %s", w.availableConnections, w.waitDuration.String())
118 return msg
119 }
120
121
122 func (w WaitQueueTimeoutError) Unwrap() error {
123 return w.Wrapped
124 }
125
View as plain text