mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 01:21:03 +01:00
SERVER-40446 Add "NonResumableChangeStreamError" error label
Give the "NonRetryableChangeStreamError" error class a more appropriate name and propagate it to an "errorLabel" in the command response.
This commit is contained in:
parent
4b7ecadd7d
commit
0e9564888a
33
jstests/change_streams/error_label.js
Normal file
33
jstests/change_streams/error_label.js
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Test that an erroneous Change Stream pipeline responds with an error that includes the
|
||||
* "NonResumableChangeStreamError" label.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
load("jstests/libs/collection_drop_recreate.js"); // For assertDropAndRecreateCollection.
|
||||
|
||||
// Drop and recreate the collections to be used in this set of tests.
|
||||
const coll = assertDropAndRecreateCollection(db, "change_stream_error_label");
|
||||
|
||||
// Attaching a projection to the Change Stream that filters out the resume token (stored in the
|
||||
// _id field) guarantees a ChangeStreamFatalError as soon as we get the first change.
|
||||
const changeStream = coll.watch([{$project: {_id: 0}}], {batchSize: 1});
|
||||
assert.commandWorked(coll.insert({a: 1}));
|
||||
|
||||
const err = assert.throws(function() {
|
||||
// Call hasNext() until it throws an error or unexpectedly returns true. We need the
|
||||
// assert.soon() to keep trying here, because the above insert command isn't immediately
|
||||
// observable to the change stream in sharded configurations.
|
||||
assert.soon(function() {
|
||||
return changeStream.hasNext();
|
||||
});
|
||||
});
|
||||
|
||||
// The hasNext() sends a getMore command, which should generate a ChangeStreamFatalError reply
|
||||
// that includes the NonResumableChangeStreamError errorLabel.
|
||||
assert.commandFailedWithCode(err, ErrorCodes.ChangeStreamFatalError);
|
||||
assert("errorLabels" in err, err);
|
||||
assert.contains("NonResumableChangeStreamError", err.errorLabels, err);
|
||||
}());
|
@ -357,4 +357,4 @@ error_class("SnapshotError", ["SnapshotTooOld", "SnapshotUnavailable", "StaleChu
|
||||
|
||||
error_class("VoteAbortError", ["NoSuchTransaction", "TransactionTooOld"])
|
||||
|
||||
error_class("NonRetryableChangeStreamError", ["ChangeStreamFatalError", "ChangeStreamHistoryLost"])
|
||||
error_class("NonResumableChangeStreamError", ["ChangeStreamFatalError", "ChangeStreamHistoryLost"])
|
||||
|
@ -36,23 +36,26 @@ BSONObj getErrorLabels(const OperationSessionInfoFromClient& sessionOptions,
|
||||
const std::string& commandName,
|
||||
ErrorCodes::Error code,
|
||||
bool hasWriteConcernError) {
|
||||
BSONArrayBuilder labelArray;
|
||||
|
||||
// By specifying "autocommit", the user indicates they want to run a transaction.
|
||||
// It is always false when set.
|
||||
if (!sessionOptions.getAutocommit()) {
|
||||
return {};
|
||||
// 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;
|
||||
}
|
||||
|
||||
// The errors that indicate the transaction fails without any persistent side-effect.
|
||||
bool isTransient = isTransientTransactionError(
|
||||
code,
|
||||
hasWriteConcernError,
|
||||
commandName == "commitTransaction" || commandName == "coordinateCommitTransaction");
|
||||
|
||||
if (isTransient) {
|
||||
return BSON("errorLabels" << BSON_ARRAY(txn::TransientTxnErrorFieldName));
|
||||
if (ErrorCodes::isNonResumableChangeStreamError(code)) {
|
||||
labelArray << "NonResumableChangeStreamError";
|
||||
}
|
||||
return {};
|
||||
|
||||
return (labelArray.arrSize() > 0) ? BSON("errorLabels" << labelArray.arr()) : BSONObj();
|
||||
}
|
||||
|
||||
} // namespace mongo
|
||||
|
Loading…
Reference in New Issue
Block a user