PYTHON-4660 Fix AttributeError when MongoClient.bulk_write batch fails with InvalidBSON (#1792)
This commit is contained in:
parent
adf8817df8
commit
297dfe6aa3
@ -550,7 +550,8 @@ class _AsyncClientBulk:
|
||||
if result.get("error"):
|
||||
error = result["error"]
|
||||
retryable_top_level_error = (
|
||||
isinstance(error.details, dict)
|
||||
hasattr(error, "details")
|
||||
and isinstance(error.details, dict)
|
||||
and error.details.get("code", 0) in _RETRYABLE_ERROR_CODES
|
||||
)
|
||||
retryable_network_error = isinstance(
|
||||
|
||||
@ -2562,7 +2562,9 @@ class _ClientConnectionRetryable(Generic[T]):
|
||||
if not self._retryable:
|
||||
raise
|
||||
if isinstance(exc, ClientBulkWriteException) and exc.error:
|
||||
retryable_write_error_exc = exc.error.has_error_label("RetryableWriteError")
|
||||
retryable_write_error_exc = isinstance(
|
||||
exc.error, PyMongoError
|
||||
) and exc.error.has_error_label("RetryableWriteError")
|
||||
else:
|
||||
retryable_write_error_exc = exc.has_error_label("RetryableWriteError")
|
||||
if retryable_write_error_exc:
|
||||
|
||||
@ -548,7 +548,8 @@ class _ClientBulk:
|
||||
if result.get("error"):
|
||||
error = result["error"]
|
||||
retryable_top_level_error = (
|
||||
isinstance(error.details, dict)
|
||||
hasattr(error, "details")
|
||||
and isinstance(error.details, dict)
|
||||
and error.details.get("code", 0) in _RETRYABLE_ERROR_CODES
|
||||
)
|
||||
retryable_network_error = isinstance(
|
||||
|
||||
@ -2549,7 +2549,9 @@ class _ClientConnectionRetryable(Generic[T]):
|
||||
if not self._retryable:
|
||||
raise
|
||||
if isinstance(exc, ClientBulkWriteException) and exc.error:
|
||||
retryable_write_error_exc = exc.error.has_error_label("RetryableWriteError")
|
||||
retryable_write_error_exc = isinstance(
|
||||
exc.error, PyMongoError
|
||||
) and exc.error.has_error_label("RetryableWriteError")
|
||||
else:
|
||||
retryable_write_error_exc = exc.has_error_label("RetryableWriteError")
|
||||
if retryable_write_error_exc:
|
||||
|
||||
@ -19,12 +19,18 @@ import sys
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from test.asynchronous import AsyncIntegrationTest, async_client_context, unittest
|
||||
from test.asynchronous import (
|
||||
AsyncIntegrationTest,
|
||||
async_client_context,
|
||||
unittest,
|
||||
)
|
||||
from test.utils import (
|
||||
OvertCommandListener,
|
||||
async_rs_or_single_client,
|
||||
)
|
||||
from unittest.mock import patch
|
||||
|
||||
from pymongo.asynchronous.client_bulk import _AsyncClientBulk
|
||||
from pymongo.encryption_options import _HAVE_PYMONGOCRYPT, AutoEncryptionOpts
|
||||
from pymongo.errors import (
|
||||
ClientBulkWriteException,
|
||||
@ -53,6 +59,20 @@ class TestClientBulkWrite(AsyncIntegrationTest):
|
||||
context.exception._message,
|
||||
)
|
||||
|
||||
@async_client_context.require_version_min(8, 0, 0, -24)
|
||||
async def test_handles_non_pymongo_error(self):
|
||||
with patch.object(
|
||||
_AsyncClientBulk, "write_command", return_value={"error": TypeError("mock type error")}
|
||||
):
|
||||
client = await async_rs_or_single_client()
|
||||
self.addAsyncCleanup(client.close)
|
||||
|
||||
models = [InsertOne(namespace="db.coll", document={"a": "b"})]
|
||||
with self.assertRaises(ClientBulkWriteException) as context:
|
||||
await client.bulk_write(models=models)
|
||||
self.assertIsInstance(context.exception.error, TypeError)
|
||||
self.assertFalse(hasattr(context.exception.error, "details"))
|
||||
|
||||
|
||||
# https://github.com/mongodb/specifications/tree/master/source/crud/tests
|
||||
class TestClientBulkWriteCRUD(AsyncIntegrationTest):
|
||||
|
||||
@ -19,11 +19,16 @@ import sys
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from test import IntegrationTest, client_context, unittest
|
||||
from test import (
|
||||
IntegrationTest,
|
||||
client_context,
|
||||
unittest,
|
||||
)
|
||||
from test.utils import (
|
||||
OvertCommandListener,
|
||||
rs_or_single_client,
|
||||
)
|
||||
from unittest.mock import patch
|
||||
|
||||
from pymongo.encryption_options import _HAVE_PYMONGOCRYPT, AutoEncryptionOpts
|
||||
from pymongo.errors import (
|
||||
@ -34,6 +39,7 @@ from pymongo.errors import (
|
||||
)
|
||||
from pymongo.monitoring import *
|
||||
from pymongo.operations import *
|
||||
from pymongo.synchronous.client_bulk import _ClientBulk
|
||||
from pymongo.write_concern import WriteConcern
|
||||
|
||||
_IS_SYNC = True
|
||||
@ -53,6 +59,20 @@ class TestClientBulkWrite(IntegrationTest):
|
||||
context.exception._message,
|
||||
)
|
||||
|
||||
@client_context.require_version_min(8, 0, 0, -24)
|
||||
def test_handles_non_pymongo_error(self):
|
||||
with patch.object(
|
||||
_ClientBulk, "write_command", return_value={"error": TypeError("mock type error")}
|
||||
):
|
||||
client = rs_or_single_client()
|
||||
self.addCleanup(client.close)
|
||||
|
||||
models = [InsertOne(namespace="db.coll", document={"a": "b"})]
|
||||
with self.assertRaises(ClientBulkWriteException) as context:
|
||||
client.bulk_write(models=models)
|
||||
self.assertIsInstance(context.exception.error, TypeError)
|
||||
self.assertFalse(hasattr(context.exception.error, "details"))
|
||||
|
||||
|
||||
# https://github.com/mongodb/specifications/tree/master/source/crud/tests
|
||||
class TestClientBulkWriteCRUD(IntegrationTest):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user