Skip to content

Commit 2af521e

Browse files
authored
PYTHON-2984 Fix retry behavior for bulk write writeConcernError (#800)
1 parent cddae7a commit 2af521e

39 files changed

+515
-95
lines changed

pymongo/bulk.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
validate_is_document_type,
2929
validate_ok_for_replace,
3030
validate_ok_for_update)
31-
from pymongo.helpers import _RETRYABLE_ERROR_CODES
31+
from pymongo.helpers import _RETRYABLE_ERROR_CODES, _get_wce_doc
3232
from pymongo.collation import validate_collation_or_none
3333
from pymongo.errors import (BulkWriteError,
3434
ConfigurationError,
@@ -119,9 +119,9 @@ def _merge_command(run, full_result, offset, result):
119119
replacement["op"] = run.ops[idx]
120120
full_result["writeErrors"].append(replacement)
121121

122-
wc_error = result.get("writeConcernError")
123-
if wc_error:
124-
full_result["writeConcernErrors"].append(wc_error)
122+
wce = _get_wce_doc(result)
123+
if wce:
124+
full_result["writeConcernErrors"].append(wce)
125125

126126

127127
def _raise_bulk_write_error(full_result):

pymongo/helpers.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,18 @@ def _raise_write_concern_error(error):
188188
error.get("errmsg"), error.get("code"), error)
189189

190190

191+
def _get_wce_doc(result):
192+
"""Return the writeConcernError or None."""
193+
wce = result.get("writeConcernError")
194+
if wce:
195+
# The server reports errorLabels at the top level but it's more
196+
# convenient to attach it to the writeConcernError doc itself.
197+
error_labels = result.get("errorLabels")
198+
if error_labels:
199+
wce["errorLabels"] = error_labels
200+
return wce
201+
202+
191203
def _check_write_command_response(result):
192204
"""Backward compatibility helper for write command error handling.
193205
"""
@@ -196,12 +208,9 @@ def _check_write_command_response(result):
196208
if write_errors:
197209
_raise_last_write_error(write_errors)
198210

199-
error = result.get("writeConcernError")
200-
if error:
201-
error_labels = result.get("errorLabels")
202-
if error_labels:
203-
error.update({'errorLabels': error_labels})
204-
_raise_write_concern_error(error)
211+
wce = _get_wce_doc(result)
212+
if wce:
213+
_raise_write_concern_error(wce)
205214

206215

207216
def _fields_list_to_dict(fields, option_name):

test/retryable_writes/bulkWrite-serverErrors.json renamed to test/retryable_writes/legacy/bulkWrite-serverErrors.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,12 @@
119119
"failCommands": [
120120
"insert"
121121
],
122+
"errorLabels": [
123+
"RetryableWriteError"
124+
],
122125
"writeConcernError": {
123126
"code": 91,
124-
"errmsg": "Replication is being shut down",
125-
"errorLabels": [
126-
"RetryableWriteError"
127-
]
127+
"errmsg": "Replication is being shut down"
128128
}
129129
}
130130
},

test/retryable_writes/deleteOne-serverErrors.json renamed to test/retryable_writes/legacy/deleteOne-serverErrors.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@
7575
"failCommands": [
7676
"delete"
7777
],
78+
"errorLabels": [
79+
"RetryableWriteError"
80+
],
7881
"writeConcernError": {
7982
"code": 91,
80-
"errmsg": "Replication is being shut down",
81-
"errorLabels": [
82-
"RetryableWriteError"
83-
]
83+
"errmsg": "Replication is being shut down"
8484
}
8585
}
8686
},

0 commit comments

Comments
 (0)