Skip to content

Commit de09181

Browse files
authored
PYTHON-4960 More informative error message for stale primary (#2115)
1 parent baf0344 commit de09181

12 files changed

+48
-17
lines changed

pymongo/topology_description.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from bson.min_key import MinKey
3434
from bson.objectid import ObjectId
3535
from pymongo import common
36-
from pymongo.errors import ConfigurationError
36+
from pymongo.errors import ConfigurationError, PyMongoError
3737
from pymongo.read_preferences import ReadPreference, _AggWritePref, _ServerMode
3838
from pymongo.server_description import ServerDescription
3939
from pymongo.server_selectors import Selection
@@ -563,7 +563,11 @@ def _update_rs_from_primary(
563563
if None not in new_election_tuple:
564564
if None not in max_election_tuple and new_election_tuple < max_election_tuple:
565565
# Stale primary, set to type Unknown.
566-
sds[server_description.address] = server_description.to_unknown()
566+
sds[server_description.address] = server_description.to_unknown(
567+
PyMongoError(
568+
f"primary marked stale due to electionId/setVersion mismatch, {new_election_tuple} is stale compared to {max_election_tuple}"
569+
)
570+
)
567571
return _check_has_primary(sds), replica_set_name, max_set_version, max_election_id
568572
max_election_id = server_description.election_id
569573

@@ -578,7 +582,11 @@ def _update_rs_from_primary(
578582
max_election_safe = tuple(MinKey() if i is None else i for i in max_election_tuple)
579583
if new_election_safe < max_election_safe:
580584
# Stale primary, set to type Unknown.
581-
sds[server_description.address] = server_description.to_unknown()
585+
sds[server_description.address] = server_description.to_unknown(
586+
PyMongoError(
587+
f"primary marked stale due to electionId/setVersion mismatch, {new_election_tuple} is stale compared to {max_election_tuple}"
588+
)
589+
)
582590
return _check_has_primary(sds), replica_set_name, max_set_version, max_election_id
583591
else:
584592
max_election_id = server_description.election_id
@@ -591,7 +599,9 @@ def _update_rs_from_primary(
591599
and server.address != server_description.address
592600
):
593601
# Reset old primary's type to Unknown.
594-
sds[server.address] = server.to_unknown()
602+
sds[server.address] = server.to_unknown(
603+
PyMongoError("primary marked stale due to discovery of newer primary")
604+
)
595605

596606
# There can be only one prior primary.
597607
break

test/asynchronous/test_discovery_and_monitoring.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ def check_outcome(self, topology, outcome):
180180
server_type_name(expected_server_type),
181181
server_type_name(actual_server_description.server_type),
182182
)
183+
expected_error = expected_server.get("error")
184+
if expected_error:
185+
self.assertIn(expected_error, str(actual_server_description.error))
183186

184187
self.assertEqual(expected_server.get("setName"), actual_server_description.replica_set_name)
185188

test/discovery_and_monitoring/rs/new_primary.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@
5858
"servers": {
5959
"a:27017": {
6060
"type": "Unknown",
61-
"setName": null
61+
"setName": null,
62+
"error": "primary marked stale due to discovery of newer primary"
6263
},
6364
"b:27017": {
6465
"type": "RSPrimary",

test/discovery_and_monitoring/rs/new_primary_new_electionid.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
"a:27017": {
7777
"type": "Unknown",
7878
"setName": null,
79-
"electionId": null
79+
"electionId": null,
80+
"error": "primary marked stale due to discovery of newer primary"
8081
},
8182
"b:27017": {
8283
"type": "RSPrimary",
@@ -123,7 +124,8 @@
123124
"a:27017": {
124125
"type": "Unknown",
125126
"setName": null,
126-
"electionId": null
127+
"electionId": null,
128+
"error": "primary marked stale due to electionId/setVersion mismatch"
127129
},
128130
"b:27017": {
129131
"type": "RSPrimary",

test/discovery_and_monitoring/rs/new_primary_new_setversion.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
"a:27017": {
7777
"type": "Unknown",
7878
"setName": null,
79-
"electionId": null
79+
"electionId": null,
80+
"error": "primary marked stale due to discovery of newer primary"
8081
},
8182
"b:27017": {
8283
"type": "RSPrimary",
@@ -123,7 +124,8 @@
123124
"a:27017": {
124125
"type": "Unknown",
125126
"setName": null,
126-
"electionId": null
127+
"electionId": null,
128+
"error": "primary marked stale due to electionId/setVersion mismatch"
127129
},
128130
"b:27017": {
129131
"type": "RSPrimary",

test/discovery_and_monitoring/rs/primary_disconnect_electionid.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@
4848
"a:27017": {
4949
"type": "Unknown",
5050
"setName": null,
51-
"electionId": null
51+
"electionId": null,
52+
"error": "primary marked stale due to discovery of newer primary"
5253
},
5354
"b:27017": {
5455
"type": "RSPrimary",
@@ -124,6 +125,7 @@
124125
"a:27017": {
125126
"type": "Unknown",
126127
"setName": null,
128+
"error": "primary marked stale due to electionId/setVersion mismatch",
127129
"electionId": null
128130
},
129131
"b:27017": {

test/discovery_and_monitoring/rs/primary_disconnect_setversion.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@
4848
"a:27017": {
4949
"type": "Unknown",
5050
"setName": null,
51-
"electionId": null
51+
"electionId": null,
52+
"error": "primary marked stale due to discovery of newer primary"
5253
},
5354
"b:27017": {
5455
"type": "RSPrimary",
@@ -124,6 +125,7 @@
124125
"a:27017": {
125126
"type": "Unknown",
126127
"setName": null,
128+
"error": "primary marked stale due to electionId/setVersion mismatch",
127129
"electionId": null
128130
},
129131
"b:27017": {

test/discovery_and_monitoring/rs/setversion_greaterthan_max_without_electionid.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@
6565
"a:27017": {
6666
"type": "Unknown",
6767
"setName": null,
68-
"electionId": null
68+
"electionId": null,
69+
"error": "primary marked stale due to discovery of newer primary"
6970
},
7071
"b:27017": {
7172
"type": "RSPrimary",

test/discovery_and_monitoring/rs/setversion_without_electionid-pre-6.0.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@
6565
"a:27017": {
6666
"type": "Unknown",
6767
"setName": null,
68-
"electionId": null
68+
"electionId": null,
69+
"error": "primary marked stale due to discovery of newer primary"
6970
},
7071
"b:27017": {
7172
"type": "RSPrimary",

test/discovery_and_monitoring/rs/use_setversion_without_electionid-pre-6.0.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@
7373
"a:27017": {
7474
"type": "Unknown",
7575
"setName": null,
76-
"electionId": null
76+
"electionId": null,
77+
"error": "primary marked stale due to discovery of newer primary"
7778
},
7879
"b:27017": {
7980
"type": "RSPrimary",
@@ -117,7 +118,8 @@
117118
"a:27017": {
118119
"type": "Unknown",
119120
"setName": null,
120-
"electionId": null
121+
"electionId": null,
122+
"error": "primary marked stale due to electionId/setVersion mismatch"
121123
},
122124
"b:27017": {
123125
"type": "RSPrimary",

test/discovery_and_monitoring/rs/use_setversion_without_electionid.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@
8181
"b:27017": {
8282
"type": "Unknown",
8383
"setName": null,
84-
"electionId": null
84+
"electionId": null,
85+
"error": "primary marked stale due to electionId/setVersion mismatch"
8586
}
8687
},
8788
"topologyType": "ReplicaSetWithPrimary",
@@ -128,7 +129,8 @@
128129
"b:27017": {
129130
"type": "Unknown",
130131
"setName": null,
131-
"electionId": null
132+
"electionId": null,
133+
"error": "primary marked stale due to electionId/setVersion mismatch"
132134
}
133135
},
134136
"topologyType": "ReplicaSetWithPrimary",

test/test_discovery_and_monitoring.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ def check_outcome(self, topology, outcome):
180180
server_type_name(expected_server_type),
181181
server_type_name(actual_server_description.server_type),
182182
)
183+
expected_error = expected_server.get("error")
184+
if expected_error:
185+
self.assertIn(expected_error, str(actual_server_description.error))
183186

184187
self.assertEqual(expected_server.get("setName"), actual_server_description.replica_set_name)
185188

0 commit comments

Comments
 (0)