summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/core/write_error_message_truncation.js42
-rw-r--r--src/mongo/db/commands/write_commands.cpp20
2 files changed, 59 insertions, 3 deletions
diff --git a/jstests/core/write_error_message_truncation.js b/jstests/core/write_error_message_truncation.js
new file mode 100644
index 00000000000..3a7a33ec86f
--- /dev/null
+++ b/jstests/core/write_error_message_truncation.js
@@ -0,0 +1,42 @@
+/**
+ * Tests that the write error messages' strings are truncated properly.
+ *
+ * @tags: [
+ * assumes_write_concern_unchanged,
+ * ]
+ */
+
+(function() {
+'use strict';
+
+var coll = db.write_error_message_truncation;
+coll.drop();
+
+// Insert 3 documents that we will then reinsert in order to generate DuplicateKey errors
+assert.writeOK(coll.insert(
+ [
+ {_id: 0},
+ {_id: 1},
+ {_id: 2},
+ ],
+ {writeConcern: {w: 'majority'}, ordered: true}));
+
+// Ensure DuplicateKey errors during insert all report their messages
+var res = coll.insert(
+ [
+ {_id: 0},
+ {_id: 1},
+ {_id: 2},
+ ],
+ {writeConcern: {w: 'majority'}, ordered: false});
+
+jsTest.log(res.getRawResponse());
+
+assert.eq(0, res.nInserted);
+
+var writeErrors = res.getWriteErrors();
+assert.eq(3, writeErrors.length);
+assert.neq('', writeErrors[0].errmsg);
+assert.neq('', writeErrors[1].errmsg);
+assert.neq('', writeErrors[2].errmsg);
+})();
diff --git a/src/mongo/db/commands/write_commands.cpp b/src/mongo/db/commands/write_commands.cpp
index 0b671d5a8aa..d562d21a00e 100644
--- a/src/mongo/db/commands/write_commands.cpp
+++ b/src/mongo/db/commands/write_commands.cpp
@@ -340,12 +340,26 @@ boost::optional<write_ops::WriteError> generateError(OperationContext* opCtx,
if (ErrorCodes::isInterruption(*overwrittenStatus)) {
uassertStatusOK(*overwrittenStatus);
}
+
+ // Tenant migration errors, similarly to migration errors consume too much space in the
+ // ordered:false responses and get truncated. Since the call to
+ // 'handleTenantMigrationConflict' above replaces the original status, we need to manually
+ // truncate the new reason if the original 'status' was also truncated.
+ if (status.reason().empty()) {
+ overwrittenStatus = overwrittenStatus->withReason("");
+ }
}
constexpr size_t kMaxErrorReasonsToReport = 1;
- if (numErrors >= kMaxErrorReasonsToReport)
- overwrittenStatus =
- overwrittenStatus ? overwrittenStatus->withReason("") : status.withReason("");
+ constexpr size_t kMaxErrorSizeToReportAfterMaxReasonsReached = 1024 * 1024;
+
+ if (numErrors > kMaxErrorReasonsToReport) {
+ size_t errorSize =
+ overwrittenStatus ? overwrittenStatus->reason().size() : status.reason().size();
+ if (errorSize > kMaxErrorSizeToReportAfterMaxReasonsReached)
+ overwrittenStatus =
+ overwrittenStatus ? overwrittenStatus->withReason("") : status.withReason("");
+ }
if (overwrittenStatus)
return write_ops::WriteError(index, std::move(*overwrittenStatus));