Skip to content

Commit b2fba41

Browse files
authored
PYTHON-2342 Prefer checking error codes over error messages (#492)
1 parent 6569933 commit b2fba41

File tree

3 files changed

+45
-56
lines changed

3 files changed

+45
-56
lines changed

pymongo/helpers.py

Lines changed: 42 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def _index_document(index_list):
102102
return index
103103

104104

105-
def _check_command_response(response, max_wire_version, msg=None,
105+
def _check_command_response(response, max_wire_version,
106106
allowable_errors=None,
107107
parse_write_concern_error=False):
108108
"""Check the response to a command for errors.
@@ -117,55 +117,47 @@ def _check_command_response(response, max_wire_version, msg=None,
117117
if parse_write_concern_error and 'writeConcernError' in response:
118118
_raise_write_concern_error(response['writeConcernError'])
119119

120-
if not response["ok"]:
121-
122-
details = response
123-
# Mongos returns the error details in a 'raw' object
124-
# for some errors.
125-
if "raw" in response:
126-
for shard in itervalues(response["raw"]):
127-
# Grab the first non-empty raw error from a shard.
128-
if shard.get("errmsg") and not shard.get("ok"):
129-
details = shard
130-
break
131-
132-
errmsg = details["errmsg"]
133-
if (allowable_errors is None
134-
or (errmsg not in allowable_errors
135-
and details.get("code") not in allowable_errors)):
136-
137-
code = details.get("code")
138-
# Server is "not master" or "recovering"
139-
if code in _NOT_MASTER_CODES:
140-
raise NotMasterError(errmsg, response)
141-
elif ("not master" in errmsg
142-
or "node is recovering" in errmsg):
143-
raise NotMasterError(errmsg, response)
144-
145-
# Server assertion failures
146-
if errmsg == "db assertion failure":
147-
errmsg = ("db assertion failure, assertion: '%s'" %
148-
details.get("assertion", ""))
149-
raise OperationFailure(errmsg,
150-
details.get("assertionCode"),
151-
response,
152-
max_wire_version)
153-
154-
# Other errors
155-
# findAndModify with upsert can raise duplicate key error
156-
if code in (11000, 11001, 12582):
157-
raise DuplicateKeyError(errmsg, code, response,
158-
max_wire_version)
159-
elif code == 50:
160-
raise ExecutionTimeout(errmsg, code, response,
161-
max_wire_version)
162-
elif code == 43:
163-
raise CursorNotFound(errmsg, code, response,
164-
max_wire_version)
165-
166-
msg = msg or "%s"
167-
raise OperationFailure(msg % errmsg, code, response,
168-
max_wire_version)
120+
if response["ok"]:
121+
return
122+
123+
details = response
124+
# Mongos returns the error details in a 'raw' object
125+
# for some errors.
126+
if "raw" in response:
127+
for shard in itervalues(response["raw"]):
128+
# Grab the first non-empty raw error from a shard.
129+
if shard.get("errmsg") and not shard.get("ok"):
130+
details = shard
131+
break
132+
133+
errmsg = details["errmsg"]
134+
code = details.get("code")
135+
136+
# For allowable errors, only check for error messages when the code is not
137+
# included.
138+
if allowable_errors:
139+
if code is not None:
140+
if code in allowable_errors:
141+
return
142+
elif errmsg in allowable_errors:
143+
return
144+
145+
# Server is "not master" or "recovering"
146+
if code in _NOT_MASTER_CODES:
147+
raise NotMasterError(errmsg, response)
148+
elif "not master" in errmsg or "node is recovering" in errmsg:
149+
raise NotMasterError(errmsg, response)
150+
151+
# Other errors
152+
# findAndModify with upsert can raise duplicate key error
153+
if code in (11000, 11001, 12582):
154+
raise DuplicateKeyError(errmsg, code, response, max_wire_version)
155+
elif code == 50:
156+
raise ExecutionTimeout(errmsg, code, response, max_wire_version)
157+
elif code == 43:
158+
raise CursorNotFound(errmsg, code, response, max_wire_version)
159+
160+
raise OperationFailure(errmsg, code, response, max_wire_version)
169161

170162

171163
def _check_gle_response(result, max_wire_version):

pymongo/network.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,7 @@ def command(sock_info, dbname, spec, slave_ok, is_mongos,
157157
client._process_response(response_doc, session)
158158
if check:
159159
helpers._check_command_response(
160-
response_doc, sock_info.max_wire_version, None,
161-
allowable_errors,
160+
response_doc, sock_info.max_wire_version, allowable_errors,
162161
parse_write_concern_error=parse_write_concern_error)
163162
except Exception as exc:
164163
if publish:

pymongo/server.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,8 @@ def run_operation_with_response(
131131
user_fields=user_fields)
132132
if use_cmd:
133133
first = docs[0]
134-
operation.client._process_response(
135-
first, operation.session)
136-
_check_command_response(
137-
first, sock_info.max_wire_version)
134+
operation.client._process_response(first, operation.session)
135+
_check_command_response(first, sock_info.max_wire_version)
138136
except Exception as exc:
139137
if publish:
140138
duration = datetime.now() - start

0 commit comments

Comments
 (0)