docs: def _check_command_response(response, msg=None, allowable_errors=None,
                              parse_write_concern_error=False):
      """Check the response to a command for errors.
      """
      if "ok" not in response:
          # Server didn't recognize our message as a command.
          raise OperationFailure(response.get("$err"),
                                 response.get("code"),
                                 response)
  
      # TODO: remove, this is moving to _check_gle_response
      if response.get("wtimeout", False):
          # MongoDB versions before 1.8.0 return the error message in an "errmsg"
          # field. If "errmsg" exists "err" will also exist set to None, so we
          # have to check for "errmsg" first.
          raise WTimeoutError(response.get("errmsg", response.get("err")),
                              response.get("code"),
                              response)
  
      if parse_write_concern_error and 'writeConcernError' in response:
          wce = response['writeConcernError']
          raise WriteConcernError(wce['errmsg'], wce['code'], wce)
  
      if not response["ok"]:
  
          details = response
          # Mongos returns the error details in a 'raw' object
          # for some errors.
          if "raw" in response:
              for shard in itervalues(response["raw"]):
                  # Grab the first non-empty raw error from a shard.
                  if shard.get("errmsg") and not shard.get("ok"):
                      details = shard
                      break
  
          errmsg = details["errmsg"]
          if allowable_errors is None or errmsg not in allowable_errors:
  
              # Server is "not master" or "recovering"
              if (errmsg.startswith("not master")
                      or errmsg.startswith("node is recovering")):
                  raise NotMasterError(errmsg, response)
  
              # Server assertion failures
              if errmsg == "db assertion failure":
                  errmsg = ("db assertion failure, assertion: '%s'" %
                            details.get("assertion", ""))
                  raise OperationFailure(errmsg,
                                         details.get("assertionCode"),
                                         response)
  
              # Other errors
              code = details.get("code")
              # findAndModify with upsert can raise duplicate key error
              if code in (11000, 11001, 12582):
                  raise DuplicateKeyError(errmsg, code, response)
              elif code == 50:
                  raise ExecutionTimeout(errmsg, code, response)
              elif code == 43:
                  raise CursorNotFound(errmsg, code, response)
  
              msg = msg or "%s"
              raise OperationFailure(msg % errmsg, code, response)