64
64
from pymongo .asynchronous .cursor import AsyncCursor
65
65
from pymongo .asynchronous .database import AsyncDatabase
66
66
from pymongo .asynchronous .mongo_client import AsyncMongoClient
67
- from pymongo .asynchronous .pool import _configured_socket , _raise_connection_failure
67
+ from pymongo .asynchronous .pool import (
68
+ _configured_socket ,
69
+ _get_timeout_details ,
70
+ _raise_connection_failure ,
71
+ )
68
72
from pymongo .common import CONNECT_TIMEOUT
69
73
from pymongo .daemon import _spawn_daemon
70
74
from pymongo .encryption_options import AutoEncryptionOpts , RangeOpts
89
93
if TYPE_CHECKING :
90
94
from pymongocrypt .mongocrypt import MongoCryptKmsContext
91
95
96
+ from pymongo .typings import _Address
97
+
92
98
93
99
_IS_SYNC = False
94
100
104
110
_KEY_VAULT_OPTS = CodecOptions (document_class = RawBSONDocument )
105
111
106
112
113
+ async def _connect_kms (address : _Address , opts : PoolOptions ):
114
+ try :
115
+ return await _configured_socket (address , opts )
116
+ except Exception as exc :
117
+ _raise_connection_failure (address , exc , timeout_details = _get_timeout_details (opts ))
118
+
119
+
107
120
@contextlib .contextmanager
108
121
def _wrap_encryption_errors () -> Iterator [None ]:
109
122
"""Context manager to wrap encryption related errors."""
@@ -176,13 +189,13 @@ async def kms_request(self, kms_context: MongoCryptKmsContext) -> None:
176
189
socket_timeout = connect_timeout ,
177
190
ssl_context = ctx ,
178
191
)
179
- host , port = parse_host (endpoint , _HTTPS_PORT )
192
+ address = parse_host (endpoint , _HTTPS_PORT )
180
193
sleep_u = kms_context .usleep
181
194
if sleep_u :
182
195
sleep_sec = float (sleep_u ) / 1e6
183
196
await asyncio .sleep (sleep_sec )
184
197
try :
185
- conn = await _configured_socket (( host , port ) , opts )
198
+ conn = await _connect_kms ( address , opts )
186
199
try :
187
200
await async_sendall (conn , message )
188
201
while kms_context .bytes_needed > 0 :
@@ -199,19 +212,21 @@ async def kms_request(self, kms_context: MongoCryptKmsContext) -> None:
199
212
if not data :
200
213
raise OSError ("KMS connection closed" )
201
214
kms_context .feed (data )
202
- except BLOCKING_IO_ERRORS :
203
- raise socket .timeout ("timed out" ) from None
215
+ except MongoCryptError :
216
+ raise # Propagate MongoCryptError errors directly.
217
+ except Exception as exc :
218
+ # Wrap I/O errors in PyMongo exceptions.
219
+ if isinstance (exc , BLOCKING_IO_ERRORS ):
220
+ exc = socket .timeout ("timed out" )
221
+ _raise_connection_failure (address , exc , timeout_details = _get_timeout_details (opts ))
204
222
finally :
205
223
conn .close ()
206
224
except MongoCryptError :
207
225
raise # Propagate MongoCryptError errors directly.
208
226
except Exception as exc :
209
227
remaining = _csot .remaining ()
210
- if isinstance (exc , (socket .timeout , NetworkTimeout )) or (
211
- remaining is not None and remaining <= 0
212
- ):
213
- # Wrap I/O errors in PyMongo exceptions.
214
- _raise_connection_failure ((host , port ), exc )
228
+ if isinstance (exc , NetworkTimeout ) or (remaining is not None and remaining <= 0 ):
229
+ raise
215
230
# Mark this attempt as failed and defer to libmongocrypt to retry.
216
231
try :
217
232
kms_context .fail ()
0 commit comments