Skip to content

Commit 7d539a2

Browse files
committed
PYTHON-2560 Fix TestCustomEndpoint, wrap error properly
1 parent 6a85e84 commit 7d539a2

File tree

2 files changed

+50
-20
lines changed

2 files changed

+50
-20
lines changed

pymongo/asynchronous/encryption.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@
6464
from pymongo.asynchronous.cursor import AsyncCursor
6565
from pymongo.asynchronous.database import AsyncDatabase
6666
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+
)
6872
from pymongo.common import CONNECT_TIMEOUT
6973
from pymongo.daemon import _spawn_daemon
7074
from pymongo.encryption_options import AutoEncryptionOpts, RangeOpts
@@ -89,6 +93,8 @@
8993
if TYPE_CHECKING:
9094
from pymongocrypt.mongocrypt import MongoCryptKmsContext
9195

96+
from pymongo.typings import _Address
97+
9298

9399
_IS_SYNC = False
94100

@@ -104,6 +110,13 @@
104110
_KEY_VAULT_OPTS = CodecOptions(document_class=RawBSONDocument)
105111

106112

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+
107120
@contextlib.contextmanager
108121
def _wrap_encryption_errors() -> Iterator[None]:
109122
"""Context manager to wrap encryption related errors."""
@@ -176,13 +189,13 @@ async def kms_request(self, kms_context: MongoCryptKmsContext) -> None:
176189
socket_timeout=connect_timeout,
177190
ssl_context=ctx,
178191
)
179-
host, port = parse_host(endpoint, _HTTPS_PORT)
192+
address = parse_host(endpoint, _HTTPS_PORT)
180193
sleep_u = kms_context.usleep
181194
if sleep_u:
182195
sleep_sec = float(sleep_u) / 1e6
183196
await asyncio.sleep(sleep_sec)
184197
try:
185-
conn = await _configured_socket((host, port), opts)
198+
conn = await _connect_kms(address, opts)
186199
try:
187200
await async_sendall(conn, message)
188201
while kms_context.bytes_needed > 0:
@@ -199,19 +212,21 @@ async def kms_request(self, kms_context: MongoCryptKmsContext) -> None:
199212
if not data:
200213
raise OSError("KMS connection closed")
201214
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))
204222
finally:
205223
conn.close()
206224
except MongoCryptError:
207225
raise # Propagate MongoCryptError errors directly.
208226
except Exception as exc:
209227
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
215230
# Mark this attempt as failed and defer to libmongocrypt to retry.
216231
try:
217232
kms_context.fail()

pymongo/synchronous/encryption.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,20 @@
8181
from pymongo.synchronous.cursor import Cursor
8282
from pymongo.synchronous.database import Database
8383
from pymongo.synchronous.mongo_client import MongoClient
84-
from pymongo.synchronous.pool import _configured_socket, _raise_connection_failure
84+
from pymongo.synchronous.pool import (
85+
_configured_socket,
86+
_get_timeout_details,
87+
_raise_connection_failure,
88+
)
8589
from pymongo.typings import _DocumentType, _DocumentTypeArg
8690
from pymongo.uri_parser import parse_host
8791
from pymongo.write_concern import WriteConcern
8892

8993
if TYPE_CHECKING:
9094
from pymongocrypt.mongocrypt import MongoCryptKmsContext
9195

96+
from pymongo.typings import _Address
97+
9298

9399
_IS_SYNC = True
94100

@@ -104,6 +110,13 @@
104110
_KEY_VAULT_OPTS = CodecOptions(document_class=RawBSONDocument)
105111

106112

113+
def _connect_kms(address: _Address, opts: PoolOptions):
114+
try:
115+
return _configured_socket(address, opts)
116+
except Exception as exc:
117+
_raise_connection_failure(address, exc, timeout_details=_get_timeout_details(opts))
118+
119+
107120
@contextlib.contextmanager
108121
def _wrap_encryption_errors() -> Iterator[None]:
109122
"""Context manager to wrap encryption related errors."""
@@ -176,13 +189,13 @@ def kms_request(self, kms_context: MongoCryptKmsContext) -> None:
176189
socket_timeout=connect_timeout,
177190
ssl_context=ctx,
178191
)
179-
host, port = parse_host(endpoint, _HTTPS_PORT)
192+
address = parse_host(endpoint, _HTTPS_PORT)
180193
sleep_u = kms_context.usleep
181194
if sleep_u:
182195
sleep_sec = float(sleep_u) / 1e6
183196
time.sleep(sleep_sec)
184197
try:
185-
conn = _configured_socket((host, port), opts)
198+
conn = _connect_kms(address, opts)
186199
try:
187200
sendall(conn, message)
188201
while kms_context.bytes_needed > 0:
@@ -199,19 +212,21 @@ def kms_request(self, kms_context: MongoCryptKmsContext) -> None:
199212
if not data:
200213
raise OSError("KMS connection closed")
201214
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))
204222
finally:
205223
conn.close()
206224
except MongoCryptError:
207225
raise # Propagate MongoCryptError errors directly.
208226
except Exception as exc:
209227
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
215230
# Mark this attempt as failed and defer to libmongocrypt to retry.
216231
try:
217232
kms_context.fail()

0 commit comments

Comments
 (0)