Skip to content

Commit fa07519

Browse files
committed
fix: unordered bulk write should attempt to execute all batches
When an unordered bulk operation is executed, it should attempt to execute all batches and only return errors after all batches have been attempted NODE-2619
1 parent 99b86b3 commit fa07519

File tree

2 files changed

+77
-3
lines changed

2 files changed

+77
-3
lines changed

lib/bulk/unordered.js

+8
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ class UnorderedBulkOperation extends BulkOperationBase {
105105

106106
super(topology, collection, options, false);
107107
}
108+
109+
handleWriteError(callback, writeResult) {
110+
if (this.s.batches.length) {
111+
return false;
112+
}
113+
114+
return super.handleWriteError(callback, writeResult);
115+
}
108116
}
109117

110118
/**

test/functional/bulk.test.js

+69-3
Original file line numberDiff line numberDiff line change
@@ -1637,9 +1637,9 @@ describe('Bulk', function() {
16371637
coll.bulkWrite(
16381638
[
16391639
{ insertOne: { _id: 5, a: 0 } },
1640-
{ updateOne: { filter: { _id: 1 }, update: { $set: { a: 0 } } } },
1640+
{ updateOne: { filter: { _id: 1 }, update: { $set: { a: 15 } } } },
16411641
{ insertOne: { _id: 6, a: 0 } },
1642-
{ updateOne: { filter: { _id: 2 }, update: { $set: { a: 0 } } } }
1642+
{ updateOne: { filter: { _id: 2 }, update: { $set: { a: 42 } } } }
16431643
],
16441644
{ ordered: false }
16451645
)
@@ -1666,7 +1666,7 @@ describe('Bulk', function() {
16661666
return client.connect().then(() => {
16671667
this.defer(() => client.close());
16681668

1669-
const coll = client.db().collection('bulk_op_ordering_test');
1669+
const coll = client.db().collection('unordered_preserve_order');
16701670
function ignoreNsNotFound(err) {
16711671
if (!err.message.match(/ns not found/)) throw err;
16721672
}
@@ -1697,4 +1697,70 @@ describe('Bulk', function() {
16971697
);
16981698
});
16991699
});
1700+
1701+
it('should not fail on the first error in an unorderd bulkWrite', function() {
1702+
const client = this.configuration.newClient();
1703+
return client.connect().then(() => {
1704+
this.defer(() => client.close());
1705+
1706+
const coll = client.db().collection('bulk_op_ordering_test');
1707+
function ignoreNsNotFound(err) {
1708+
if (!err.message.match(/ns not found/)) throw err;
1709+
}
1710+
1711+
return coll
1712+
.drop()
1713+
.catch(ignoreNsNotFound)
1714+
.then(() => coll.createIndex({ email: 1 }, { unique: 1, background: false }))
1715+
.then(() =>
1716+
Promise.all([
1717+
coll.updateOne(
1718+
{ email: 'adam@gmail.com' },
1719+
{ $set: { name: 'Adam Smith', age: 29 } },
1720+
{ upsert: true }
1721+
),
1722+
coll.updateOne(
1723+
{ email: 'john@gmail.com' },
1724+
{ $set: { name: 'John Doe', age: 32 } },
1725+
{ upsert: true }
1726+
)
1727+
])
1728+
)
1729+
.then(() =>
1730+
coll.bulkWrite(
1731+
[
1732+
{
1733+
updateOne: {
1734+
filter: { email: 'adam@gmail.com' },
1735+
update: { $set: { age: 39 } }
1736+
}
1737+
},
1738+
{
1739+
insertOne: {
1740+
document: {
1741+
email: 'john@gmail.com'
1742+
}
1743+
}
1744+
}
1745+
],
1746+
{ ordered: false }
1747+
)
1748+
)
1749+
.then(
1750+
() => {
1751+
throw new Error('expected a bulk error');
1752+
},
1753+
err =>
1754+
expect(err)
1755+
.property('code')
1756+
.to.equal(11000)
1757+
)
1758+
.then(() => coll.findOne({ email: 'adam@gmail.com' }))
1759+
.then(updatedAdam =>
1760+
expect(updatedAdam)
1761+
.property('age')
1762+
.to.equal(39)
1763+
);
1764+
});
1765+
});
17001766
});

0 commit comments

Comments
 (0)