BSONObj getErrorLabels(const OperationSessionInfoFromClient& sessionOptions, const std::string& commandName, ErrorCodes::Error code, bool hasWriteConcernError) { BSONArrayBuilder labelArray; // Note that we only apply the TransientTxnError label if the "autocommit" field is present in // the session options. When present, "autocommit" will always be false, so we don't check its // value. if (sessionOptions.getAutocommit() && isTransientTransactionError(code, hasWriteConcernError, commandName == "commitTransaction" || commandName == "coordinateCommitTransaction")) { // An error code for which isTransientTransactionError() is true indicates a transaction // failure with no persistent side effects. labelArray << txn::TransientTxnErrorFieldName; } if (ErrorCodes::isNonResumableChangeStreamError(code)) { labelArray << "NonResumableChangeStreamError"; } return (labelArray.arrSize() > 0) ? BSON("errorLabels" << labelArray.arr()) : BSONObj(); }
void validateSessionOptions(const OperationSessionInfoFromClient& sessionOptions, StringData cmdName, StringData dbname) { if (sessionOptions.getAutocommit()) { uassertStatusOK(CommandHelpers::canUseTransactions(dbname, cmdName)); } if (sessionOptions.getTxnNumber()) { uassert(50768, str::stream() << "It is illegal to provide a txnNumber for command " << cmdName, commandCanCheckOutSession(cmdName) || shouldCommandSkipSessionCheckout(cmdName)); } if (sessionOptions.getStartTransaction()) { uassert(ErrorCodes::OperationNotSupportedInTransaction, "Cannot run killCursors as the first operation in a multi-document transaction.", cmdName != "killCursors"); } }