Skip to content

Commit 0ef2516

Browse files
author
Kwabena Ampofo
authored
fix(NODE-3565): Improve error message for insertMany with partially empty array (#3221)
1 parent 79a917b commit 0ef2516

File tree

3 files changed

+95
-2
lines changed

3 files changed

+95
-2
lines changed

src/bulk/common.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,9 @@ export abstract class BulkOperationBase {
11331133

11341134
/** Specifies a raw operation to perform in the bulk write. */
11351135
raw(op: AnyBulkWriteOperation): this {
1136+
if (op == null || typeof op !== 'object') {
1137+
throw new MongoInvalidArgumentError('Operation must be an object with an operation key');
1138+
}
11361139
if ('insertOne' in op) {
11371140
const forceServerObjectId = shouldForceServerObjectId(this);
11381141
if (op.insertOne && op.insertOne.document == null) {

src/operations/insert.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,14 @@ export class InsertManyOperation extends AbstractOperation<InsertManyResult> {
136136
);
137137

138138
bulkWriteOperation.execute(server, session, (err, res) => {
139-
if (err || res == null) return callback(err);
139+
if (err || res == null) {
140+
if (err && err.message === 'Operation must be an object with an operation key') {
141+
err = new MongoInvalidArgumentError(
142+
'Collection.insertMany() cannot be called with an array that has null/undefined values'
143+
);
144+
}
145+
return callback(err);
146+
}
140147
callback(undefined, {
141148
acknowledged: writeConcern?.w !== 0 ?? true,
142149
insertedCount: res.insertedCount,

test/integration/crud/bulk.test.js

+84-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ const {
77
ignoreNsNotFound,
88
assert: test
99
} = require('../shared');
10-
const { Long, MongoBatchReExecutionError, MongoDriverError } = require('../../../src');
10+
const {
11+
Long,
12+
MongoBatchReExecutionError,
13+
MongoDriverError,
14+
MongoInvalidArgumentError
15+
} = require('../../../src');
1116
const crypto = require('crypto');
1217
const chai = require('chai');
1318

@@ -22,6 +27,84 @@ describe('Bulk', function () {
2227
before(function () {
2328
return setupDatabase(this.configuration);
2429
});
30+
describe('BulkOperationBase', () => {
31+
describe('#raw()', function () {
32+
let client;
33+
beforeEach(async function () {
34+
client = this.configuration.newClient();
35+
await client.connect();
36+
});
37+
afterEach(async function () {
38+
await client.close();
39+
});
40+
context('when called with an undefined operation', function () {
41+
it('should throw a MongoInvalidArgument error ', async function () {
42+
const bulkOp = client.db('test').collection('test').initializeUnorderedBulkOp();
43+
expect(() => bulkOp.raw(undefined)).to.throw(MongoInvalidArgumentError);
44+
expect(() => bulkOp.raw(true)).to.throw(MongoInvalidArgumentError);
45+
expect(() => bulkOp.raw(3)).to.throw(MongoInvalidArgumentError);
46+
});
47+
48+
it('should throw an error with the specifc message: "Operation must be an object with an operation key"', async function () {
49+
const bulkOp = client.db('test').collection('test').initializeUnorderedBulkOp();
50+
expect(() => bulkOp.raw(undefined))
51+
.to.throw(MongoInvalidArgumentError)
52+
.to.match(/Operation must be an object with an operation key/);
53+
});
54+
});
55+
56+
context('when called with a valid operation', function () {
57+
it('should not throw a MongoInvalidArgument error', async function () {
58+
try {
59+
client.db('test').collection('test').initializeUnorderedBulkOp().raw({ insertOne: {} });
60+
} catch (error) {
61+
expect(error).not.to.exist;
62+
}
63+
});
64+
});
65+
});
66+
});
67+
68+
describe('Collection', function () {
69+
describe('#insertMany()', function () {
70+
let client;
71+
beforeEach(async function () {
72+
client = this.configuration.newClient();
73+
await client.connect();
74+
});
75+
afterEach(async function () {
76+
await client.close();
77+
});
78+
context('when passed an invalid docs argument', function () {
79+
it('should throw a MongoInvalidArgument error', async function () {
80+
try {
81+
const docs = [];
82+
docs[1] = { color: 'red' };
83+
await client.db('test').collection('test').insertMany(docs);
84+
expect.fail('Expected insertMany to throw error, failed to throw error');
85+
} catch (error) {
86+
expect(error).to.be.instanceOf(MongoInvalidArgumentError);
87+
expect(error.message).to.equal(
88+
'Collection.insertMany() cannot be called with an array that has null/undefined values'
89+
);
90+
}
91+
});
92+
});
93+
context('when passed a valid document list', function () {
94+
it('insertMany should not throw a MongoInvalidArgument error when called with a valid operation', async function () {
95+
try {
96+
let result = await client
97+
.db('test')
98+
.collection('test')
99+
.insertMany([{ color: 'blue' }]);
100+
expect(result).to.exist;
101+
} catch (error) {
102+
expect(error).not.to.exist;
103+
}
104+
});
105+
});
106+
});
107+
});
25108

26109
context('promise tests', () => {
27110
it('Should correctly execute unordered bulk operation in promise form', function (done) {

0 commit comments

Comments
 (0)