PYTHON-2572 Introduce NotPrimaryError and deprecate NotMasterError (#646)
(cherry picked from commit ff6ca53328)
This commit is contained in:
parent
ccb62d4c1b
commit
9d757265c9
@ -41,6 +41,8 @@ Deprecations
|
||||
and :meth:`~pymongo.database.Database.profiling_info`. Instead, users
|
||||
should run the `profile command`_ with the
|
||||
:meth:`~pymongo.database.Database.command` helper directly.
|
||||
- Deprecated :exc:`~pymongo.errors.NotMasterError`. Users should
|
||||
use :exc:`~pymongo.errors.NotPrimaryError` instead.
|
||||
|
||||
.. _PYTHON-2466: https://jira.mongodb.org/browse/PYTHON-2466
|
||||
.. _PYTHON-1690: https://jira.mongodb.org/browse/PYTHON-1690
|
||||
|
||||
@ -41,11 +41,11 @@ _RESUMABLE_GETMORE_ERRORS = frozenset([
|
||||
189, # PrimarySteppedDown
|
||||
262, # ExceededTimeLimit
|
||||
9001, # SocketException
|
||||
10107, # NotMaster
|
||||
10107, # NotWritablePrimary
|
||||
11600, # InterruptedAtShutdown
|
||||
11602, # InterruptedDueToReplStateChange
|
||||
13435, # NotMasterNoSlaveOk
|
||||
13436, # NotMasterOrSecondary
|
||||
13435, # NotPrimaryNoSecondaryOk
|
||||
13436, # NotPrimaryOrSecondary
|
||||
63, # StaleShardVersion
|
||||
150, # StaleEpoch
|
||||
13388, # StaleConfig
|
||||
|
||||
@ -109,7 +109,22 @@ def _format_detailed_error(message, details):
|
||||
|
||||
|
||||
class NotMasterError(AutoReconnect):
|
||||
"""The server responded "not master" or "node is recovering".
|
||||
"""**DEPRECATED** - The server responded "not master" or
|
||||
"node is recovering".
|
||||
|
||||
This exception has been deprecated and will be removed in PyMongo 4.0.
|
||||
Use :exc:`~pymongo.errors.NotPrimaryError` instead.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
Deprecated. Use :exc:`~pymongo.errors.NotPrimaryError` instead.
|
||||
"""
|
||||
def __init__(self, message='', errors=None):
|
||||
super(NotMasterError, self).__init__(
|
||||
_format_detailed_error(message, errors), errors=errors)
|
||||
|
||||
|
||||
class NotPrimaryError(NotMasterError):
|
||||
"""The server responded "not primary" or "node is recovering".
|
||||
|
||||
These errors result from a query, write, or command. The operation failed
|
||||
because the client thought it was using the primary but the primary has
|
||||
@ -120,10 +135,11 @@ class NotMasterError(AutoReconnect):
|
||||
its view of the server as soon as possible after throwing this exception.
|
||||
|
||||
Subclass of :exc:`~pymongo.errors.AutoReconnect`.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
"""
|
||||
def __init__(self, message='', errors=None):
|
||||
super(NotMasterError, self).__init__(
|
||||
_format_detailed_error(message, errors), errors=errors)
|
||||
super(NotPrimaryError, self).__init__(message, errors=errors)
|
||||
|
||||
|
||||
class ServerSelectionTimeoutError(AutoReconnect):
|
||||
|
||||
@ -23,7 +23,7 @@ from pymongo import ASCENDING
|
||||
from pymongo.errors import (CursorNotFound,
|
||||
DuplicateKeyError,
|
||||
ExecutionTimeout,
|
||||
NotMasterError,
|
||||
NotPrimaryError,
|
||||
OperationFailure,
|
||||
WriteError,
|
||||
WriteConcernError,
|
||||
@ -34,15 +34,15 @@ _SHUTDOWN_CODES = frozenset([
|
||||
11600, # InterruptedAtShutdown
|
||||
91, # ShutdownInProgress
|
||||
])
|
||||
# From the SDAM spec, the "not master" error codes are combined with the
|
||||
# From the SDAM spec, the "not primary" error codes are combined with the
|
||||
# "node is recovering" error codes (of which the "node is shutting down"
|
||||
# errors are a subset).
|
||||
_NOT_MASTER_CODES = frozenset([
|
||||
10058, # LegacyNotPrimary <=3.2 "not master" error code
|
||||
10107, # NotMaster
|
||||
13435, # NotMasterNoSlaveOk
|
||||
10058, # LegacyNotPrimary <=3.2 "not primary" error code
|
||||
10107, # NotWritablePrimary
|
||||
13435, # NotPrimaryNoSecondaryOk
|
||||
11602, # InterruptedDueToReplStateChange
|
||||
13436, # NotMasterOrSecondary
|
||||
13436, # NotPrimaryOrSecondary
|
||||
189, # PrimarySteppedDown
|
||||
]) | _SHUTDOWN_CODES
|
||||
# From the retryable writes spec.
|
||||
@ -147,12 +147,12 @@ def _check_command_response(response, max_wire_version,
|
||||
elif errmsg in allowable_errors:
|
||||
return
|
||||
|
||||
# Server is "not master" or "recovering"
|
||||
# Server is "not primary" or "recovering"
|
||||
if code is not None:
|
||||
if code in _NOT_MASTER_CODES:
|
||||
raise NotMasterError(errmsg, response)
|
||||
raise NotPrimaryError(errmsg, response)
|
||||
elif "not master" in errmsg or "node is recovering" in errmsg:
|
||||
raise NotMasterError(errmsg, response)
|
||||
raise NotPrimaryError(errmsg, response)
|
||||
|
||||
# Other errors
|
||||
# findAndModify with upsert can raise duplicate key error
|
||||
@ -184,7 +184,7 @@ def _check_gle_response(result, max_wire_version):
|
||||
return result
|
||||
|
||||
if error_msg.startswith("not master"):
|
||||
raise NotMasterError(error_msg, result)
|
||||
raise NotPrimaryError(error_msg, result)
|
||||
|
||||
details = result
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ from pymongo.errors import (ConfigurationError,
|
||||
DocumentTooLarge,
|
||||
ExecutionTimeout,
|
||||
InvalidOperation,
|
||||
NotMasterError,
|
||||
NotPrimaryError,
|
||||
OperationFailure,
|
||||
ProtocolError)
|
||||
from pymongo.read_concern import DEFAULT_READ_CONCERN
|
||||
@ -997,7 +997,7 @@ class _BulkWriteContext(object):
|
||||
if isinstance(exc, OperationFailure):
|
||||
failure = _convert_write_result(
|
||||
self.name, cmd, exc.details)
|
||||
elif isinstance(exc, NotMasterError):
|
||||
elif isinstance(exc, NotPrimaryError):
|
||||
failure = exc.details
|
||||
else:
|
||||
failure = _convert_exception(exc)
|
||||
@ -1022,7 +1022,7 @@ class _BulkWriteContext(object):
|
||||
except Exception as exc:
|
||||
if self.publish:
|
||||
duration = (datetime.datetime.now() - start) + duration
|
||||
if isinstance(exc, (NotMasterError, OperationFailure)):
|
||||
if isinstance(exc, (NotPrimaryError, OperationFailure)):
|
||||
failure = exc.details
|
||||
else:
|
||||
failure = _convert_exception(exc)
|
||||
@ -1516,7 +1516,7 @@ class _OpReply(object):
|
||||
|
||||
Check the response for errors and unpack.
|
||||
|
||||
Can raise CursorNotFound, NotMasterError, ExecutionTimeout, or
|
||||
Can raise CursorNotFound, NotPrimaryError, ExecutionTimeout, or
|
||||
OperationFailure.
|
||||
|
||||
:Parameters:
|
||||
@ -1539,7 +1539,7 @@ class _OpReply(object):
|
||||
# Fake the ok field if it doesn't exist.
|
||||
error_object.setdefault("ok", 0)
|
||||
if error_object["$err"].startswith("not master"):
|
||||
raise NotMasterError(error_object["$err"], error_object)
|
||||
raise NotPrimaryError(error_object["$err"], error_object)
|
||||
elif error_object.get("code") == 50:
|
||||
raise ExecutionTimeout(error_object.get("$err"),
|
||||
error_object.get("code"),
|
||||
@ -1560,7 +1560,7 @@ class _OpReply(object):
|
||||
Check the response for errors and unpack, returning a dictionary
|
||||
containing the response data.
|
||||
|
||||
Can raise CursorNotFound, NotMasterError, ExecutionTimeout, or
|
||||
Can raise CursorNotFound, NotPrimaryError, ExecutionTimeout, or
|
||||
OperationFailure.
|
||||
|
||||
:Parameters:
|
||||
@ -1721,7 +1721,7 @@ def _first_batch(sock_info, db, coll, query, ntoreturn,
|
||||
except Exception as exc:
|
||||
if publish:
|
||||
duration = (datetime.datetime.now() - start) + encoding_duration
|
||||
if isinstance(exc, (NotMasterError, OperationFailure)):
|
||||
if isinstance(exc, (NotPrimaryError, OperationFailure)):
|
||||
failure = exc.details
|
||||
else:
|
||||
failure = _convert_exception(exc)
|
||||
|
||||
@ -59,7 +59,7 @@ from pymongo.errors import (AutoReconnect,
|
||||
ConfigurationError,
|
||||
ConnectionFailure,
|
||||
InvalidOperation,
|
||||
NotMasterError,
|
||||
NotPrimaryError,
|
||||
OperationFailure,
|
||||
PyMongoError,
|
||||
ServerSelectionTimeoutError)
|
||||
@ -2289,7 +2289,7 @@ def _retryable_error_doc(exc):
|
||||
wces = exc.details['writeConcernErrors']
|
||||
wce = wces[-1] if wces else None
|
||||
return wce
|
||||
if isinstance(exc, (NotMasterError, OperationFailure)):
|
||||
if isinstance(exc, (NotPrimaryError, OperationFailure)):
|
||||
return exc.details
|
||||
return None
|
||||
|
||||
@ -2314,10 +2314,10 @@ def _add_retryable_write_error(exc, max_wire_version):
|
||||
if code in helpers._RETRYABLE_ERROR_CODES:
|
||||
exc._add_error_label("RetryableWriteError")
|
||||
|
||||
# Connection errors are always retryable except NotMasterError which is
|
||||
# Connection errors are always retryable except NotPrimaryError which is
|
||||
# handled above.
|
||||
if (isinstance(exc, ConnectionFailure) and
|
||||
not isinstance(exc, NotMasterError)):
|
||||
not isinstance(exc, NotPrimaryError)):
|
||||
exc._add_error_label("RetryableWriteError")
|
||||
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import weakref
|
||||
from bson.py3compat import PY3
|
||||
|
||||
from pymongo import common, periodic_executor
|
||||
from pymongo.errors import (NotMasterError,
|
||||
from pymongo.errors import (NotPrimaryError,
|
||||
OperationFailure,
|
||||
_OperationCancelled)
|
||||
from pymongo.ismaster import IsMaster
|
||||
@ -215,7 +215,7 @@ class Monitor(MonitorBase):
|
||||
try:
|
||||
try:
|
||||
return self._check_once()
|
||||
except (OperationFailure, NotMasterError) as exc:
|
||||
except (OperationFailure, NotPrimaryError) as exc:
|
||||
# Update max cluster time even when isMaster fails.
|
||||
self._topology.receive_cluster_time(
|
||||
exc.details.get('$clusterTime'))
|
||||
|
||||
@ -27,7 +27,7 @@ from pymongo import helpers, message
|
||||
from pymongo.common import MAX_MESSAGE_SIZE
|
||||
from pymongo.compression_support import decompress, _NO_COMPRESSION
|
||||
from pymongo.errors import (AutoReconnect,
|
||||
NotMasterError,
|
||||
NotPrimaryError,
|
||||
OperationFailure,
|
||||
ProtocolError,
|
||||
NetworkTimeout,
|
||||
@ -163,7 +163,7 @@ def command(sock_info, dbname, spec, slave_ok, is_mongos,
|
||||
except Exception as exc:
|
||||
if publish:
|
||||
duration = (datetime.datetime.now() - start) + encoding_duration
|
||||
if isinstance(exc, (NotMasterError, OperationFailure)):
|
||||
if isinstance(exc, (NotPrimaryError, OperationFailure)):
|
||||
failure = exc.details
|
||||
else:
|
||||
failure = message._convert_exception(exc)
|
||||
|
||||
@ -48,7 +48,7 @@ from pymongo.errors import (AutoReconnect,
|
||||
InvalidOperation,
|
||||
DocumentTooLarge,
|
||||
NetworkTimeout,
|
||||
NotMasterError,
|
||||
NotPrimaryError,
|
||||
OperationFailure,
|
||||
PyMongoError)
|
||||
from pymongo.hello import HelloCompat
|
||||
@ -755,7 +755,7 @@ class SocketInfo(object):
|
||||
unacknowledged=unacknowledged,
|
||||
user_fields=user_fields,
|
||||
exhaust_allowed=exhaust_allowed)
|
||||
except (OperationFailure, NotMasterError):
|
||||
except (OperationFailure, NotPrimaryError):
|
||||
raise
|
||||
# Catch socket.error, KeyboardInterrupt, etc. and close ourselves.
|
||||
except BaseException as error:
|
||||
@ -789,13 +789,13 @@ class SocketInfo(object):
|
||||
self._raise_connection_failure(error)
|
||||
|
||||
def _raise_if_not_writable(self, unacknowledged):
|
||||
"""Raise NotMasterError on unacknowledged write if this socket is not
|
||||
"""Raise NotPrimaryError on unacknowledged write if this socket is not
|
||||
writable.
|
||||
"""
|
||||
if unacknowledged and not self.is_writable:
|
||||
# Write won't succeed, bail as if we'd received a not master error.
|
||||
raise NotMasterError("not master", {
|
||||
"ok": 0, "errmsg": "not master", "code": 10107})
|
||||
# Write won't succeed, bail as if we'd received a not primary error.
|
||||
raise NotPrimaryError("not primary", {
|
||||
"ok": 0, "errmsg": "not primary", "code": 10107})
|
||||
|
||||
def legacy_write(self, request_id, msg, max_doc_size, with_last_error):
|
||||
"""Send OP_INSERT, etc., optionally returning response as a dict.
|
||||
@ -830,7 +830,7 @@ class SocketInfo(object):
|
||||
reply = self.receive_message(request_id)
|
||||
result = reply.command_response()
|
||||
|
||||
# Raises NotMasterError or OperationFailure.
|
||||
# Raises NotPrimaryError or OperationFailure.
|
||||
helpers._check_command_response(result, self.max_wire_version)
|
||||
return result
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ from datetime import datetime
|
||||
|
||||
from bson import _decode_all_selective
|
||||
|
||||
from pymongo.errors import NotMasterError, OperationFailure
|
||||
from pymongo.errors import NotPrimaryError, OperationFailure
|
||||
from pymongo.helpers import _check_command_response
|
||||
from pymongo.message import _convert_exception, _OpMsg
|
||||
from pymongo.response import Response, PinnedResponse
|
||||
@ -130,7 +130,7 @@ class Server(object):
|
||||
except Exception as exc:
|
||||
if publish:
|
||||
duration = datetime.now() - start
|
||||
if isinstance(exc, (NotMasterError, OperationFailure)):
|
||||
if isinstance(exc, (NotPrimaryError, OperationFailure)):
|
||||
failure = exc.details
|
||||
else:
|
||||
failure = _convert_exception(exc)
|
||||
|
||||
@ -37,7 +37,7 @@ from pymongo.topology_description import (updated_topology_description,
|
||||
from pymongo.errors import (ConnectionFailure,
|
||||
ConfigurationError,
|
||||
NetworkTimeout,
|
||||
NotMasterError,
|
||||
NotPrimaryError,
|
||||
OperationFailure,
|
||||
ServerSelectionTimeoutError,
|
||||
WriteError)
|
||||
@ -425,7 +425,7 @@ class Topology(object):
|
||||
|
||||
def handle_getlasterror(self, address, error_msg):
|
||||
"""Clear our pool for a server, mark it Unknown, and check it soon."""
|
||||
error = NotMasterError(error_msg, {'code': 10107, 'errmsg': error_msg})
|
||||
error = NotPrimaryError(error_msg, {'code': 10107, 'errmsg': error_msg})
|
||||
with self._lock:
|
||||
server = self._servers.get(address)
|
||||
if server:
|
||||
@ -608,9 +608,9 @@ class Topology(object):
|
||||
elif issubclass(exc_type, WriteError):
|
||||
# Ignore writeErrors.
|
||||
return
|
||||
elif issubclass(exc_type, NotMasterError):
|
||||
elif issubclass(exc_type, NotPrimaryError):
|
||||
# As per the SDAM spec if:
|
||||
# - the server sees a "not master" error, and
|
||||
# - the server sees a "not primary" error, and
|
||||
# - the server is not shutting down, and
|
||||
# - the server version is >= 4.2, then
|
||||
# we keep the existing connection pool, but mark the server type
|
||||
|
||||
@ -20,7 +20,7 @@ sys.path[0:0] = [""]
|
||||
|
||||
from bson import SON
|
||||
from pymongo import monitoring
|
||||
from pymongo.errors import NotMasterError
|
||||
from pymongo.errors import NotPrimaryError
|
||||
from pymongo.write_concern import WriteConcern
|
||||
|
||||
from test import (client_context,
|
||||
@ -93,10 +93,10 @@ class TestConnectionsSurvivePrimaryStepDown(IntegrationTest):
|
||||
# Verify pool not cleared.
|
||||
self.verify_pool_not_cleared()
|
||||
# Attempt insertion to mark server description as stale and prevent a
|
||||
# notMaster error on the subsequent operation.
|
||||
# NotPrimaryError on the subsequent operation.
|
||||
try:
|
||||
self.coll.insert_one({})
|
||||
except NotMasterError:
|
||||
except NotPrimaryError:
|
||||
pass
|
||||
# Next insert should succeed on the new primary without clearing pool.
|
||||
self.coll.insert_one({})
|
||||
@ -109,7 +109,7 @@ class TestConnectionsSurvivePrimaryStepDown(IntegrationTest):
|
||||
"errorCode": error_code}})
|
||||
self.addCleanup(self.set_fail_point, {"mode": "off"})
|
||||
# Insert record and verify failure.
|
||||
with self.assertRaises(NotMasterError) as exc:
|
||||
with self.assertRaises(NotPrimaryError) as exc:
|
||||
self.coll.insert_one({"test": 1})
|
||||
self.assertEqual(exc.exception.details['code'], error_code)
|
||||
# Retry before CMAPListener assertion if retry_before=True.
|
||||
|
||||
@ -27,7 +27,7 @@ from pymongo import (common,
|
||||
from pymongo.errors import (AutoReconnect,
|
||||
ConfigurationError,
|
||||
NetworkTimeout,
|
||||
NotMasterError,
|
||||
NotPrimaryError,
|
||||
OperationFailure)
|
||||
from pymongo.helpers import (_check_command_response,
|
||||
_check_write_command_response)
|
||||
@ -122,7 +122,7 @@ def got_app_error(topology, app_error):
|
||||
else:
|
||||
raise AssertionError('unknown error type: %s' % (error_type,))
|
||||
assert False
|
||||
except (AutoReconnect, NotMasterError, OperationFailure) as e:
|
||||
except (AutoReconnect, NotPrimaryError, OperationFailure) as e:
|
||||
if when == 'beforeHandshakeCompletes':
|
||||
completed_handshake = False
|
||||
elif when == 'afterHandshakeCompletes':
|
||||
|
||||
@ -20,6 +20,7 @@ sys.path[0:0] = [""]
|
||||
|
||||
from pymongo.errors import (BulkWriteError,
|
||||
EncryptionError,
|
||||
NotPrimaryError,
|
||||
NotMasterError,
|
||||
OperationFailure)
|
||||
from test import (PyMongoTestCase,
|
||||
@ -27,12 +28,12 @@ from test import (PyMongoTestCase,
|
||||
|
||||
|
||||
class TestErrors(PyMongoTestCase):
|
||||
def test_not_master_error(self):
|
||||
exc = NotMasterError("not master test", {"errmsg": "error"})
|
||||
def test_not_primary_error(self):
|
||||
exc = NotPrimaryError("not primary test", {"errmsg": "error"})
|
||||
self.assertIn("full error", str(exc))
|
||||
try:
|
||||
raise exc
|
||||
except NotMasterError:
|
||||
except NotPrimaryError:
|
||||
self.assertIn("full error", traceback.format_exc())
|
||||
|
||||
def test_operation_failure(self):
|
||||
@ -66,8 +67,8 @@ class TestErrors(PyMongoTestCase):
|
||||
self._test_unicode_strs(exc)
|
||||
|
||||
def test_unicode_strs_not_master_error(self):
|
||||
exc = NotMasterError(u'unicode \U0001f40d',
|
||||
{"errmsg": u'unicode \U0001f40d'})
|
||||
exc = NotPrimaryError(u'unicode \U0001f40d',
|
||||
{"errmsg": u'unicode \U0001f40d'})
|
||||
self._test_unicode_strs(exc)
|
||||
|
||||
def assertPyMongoErrorEqual(self, exc1, exc2):
|
||||
@ -82,8 +83,8 @@ class TestErrors(PyMongoTestCase):
|
||||
self.assertEqual(exc1.details, exc2.details)
|
||||
self.assertEqual(exc1._max_wire_version, exc2._max_wire_version)
|
||||
|
||||
def test_pickle_NotMasterError(self):
|
||||
exc = NotMasterError("not master test", {"errmsg": "error"})
|
||||
def test_pickle_NotPrimaryError(self):
|
||||
exc = NotPrimaryError("not primary test", {"errmsg": "error"})
|
||||
self.assertPyMongoErrorEqual(exc, pickle.loads(pickle.dumps(exc)))
|
||||
|
||||
def test_pickle_OperationFailure(self):
|
||||
@ -103,6 +104,11 @@ class TestErrors(PyMongoTestCase):
|
||||
self.assertPyMongoErrorEqual(exc, exc2)
|
||||
self.assertOperationFailureEqual(cause, exc2.cause)
|
||||
|
||||
def test_NotMasterError_catches_NotPrimaryError(self):
|
||||
with self.assertRaises(NotMasterError) as exc:
|
||||
raise NotPrimaryError("not primary test", {"errmsg": "error"})
|
||||
self.assertIn("full error", str(exc.exception))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@ -27,7 +27,7 @@ from bson.son import SON
|
||||
from pymongo import CursorType, monitoring, InsertOne, UpdateOne, DeleteOne
|
||||
from pymongo.command_cursor import CommandCursor
|
||||
from pymongo.errors import (AutoReconnect,
|
||||
NotMasterError,
|
||||
NotPrimaryError,
|
||||
OperationFailure)
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from pymongo.write_concern import WriteConcern
|
||||
@ -440,7 +440,7 @@ class TestCommandMonitoring(PyMongoTestCase):
|
||||
error = None
|
||||
try:
|
||||
client.pymongo_test.test.find_one_and_delete({})
|
||||
except NotMasterError as exc:
|
||||
except NotPrimaryError as exc:
|
||||
error = exc.errors
|
||||
results = self.listener.results
|
||||
started = results['started'][0]
|
||||
@ -1212,7 +1212,7 @@ class TestCommandMonitoring(PyMongoTestCase):
|
||||
},
|
||||
}
|
||||
with self.fail_point(insert_command_error):
|
||||
with self.assertRaises(NotMasterError):
|
||||
with self.assertRaises(NotPrimaryError):
|
||||
coll.bulk_write([InsertOne({'_id': 1})])
|
||||
failed = self.listener.results['failed']
|
||||
self.assertEqual(1, len(failed))
|
||||
|
||||
@ -25,7 +25,7 @@ from bson.json_util import object_hook
|
||||
from pymongo import monitoring
|
||||
from pymongo.common import clean_node
|
||||
from pymongo.errors import (ConnectionFailure,
|
||||
NotMasterError)
|
||||
NotPrimaryError)
|
||||
from pymongo.ismaster import IsMaster
|
||||
from pymongo.monitor import Monitor
|
||||
from pymongo.server_description import ServerDescription
|
||||
@ -333,12 +333,12 @@ class TestSdamMonitoring(IntegrationTest):
|
||||
def test_not_master_error_publishes_events(self):
|
||||
self._test_app_error({'errorCode': 10107, 'closeConnection': False,
|
||||
'errorLabels': ['RetryableWriteError']},
|
||||
NotMasterError)
|
||||
NotPrimaryError)
|
||||
|
||||
def test_shutdown_error_publishes_events(self):
|
||||
self._test_app_error({'errorCode': 91, 'closeConnection': False,
|
||||
'errorLabels': ['RetryableWriteError']},
|
||||
NotMasterError)
|
||||
NotPrimaryError)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -39,7 +39,7 @@ from pymongo.change_stream import ChangeStream
|
||||
from pymongo.collection import Collection
|
||||
from pymongo.database import Database
|
||||
from pymongo.errors import (
|
||||
BulkWriteError, ConnectionFailure, InvalidOperation, NotMasterError,
|
||||
BulkWriteError, ConnectionFailure, InvalidOperation, NotPrimaryError,
|
||||
PyMongoError)
|
||||
from pymongo.monitoring import (
|
||||
CommandFailedEvent, CommandListener, CommandStartedEvent,
|
||||
@ -730,7 +730,7 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
if is_client_error:
|
||||
# Connection errors are considered client errors.
|
||||
if isinstance(exception, ConnectionFailure):
|
||||
self.assertNotIsInstance(exception, NotMasterError)
|
||||
self.assertNotIsInstance(exception, NotPrimaryError)
|
||||
else:
|
||||
self.assertNotIsInstance(exception, PyMongoError)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user