Skip to content

Commit 25bd7d8

Browse files
authored
Merge pull request Automattic#15206 from Automattic/vkarpov15/Automatticgh-15188
fix(aggregate): improve error when calling `near()` with invalid coordinates
2 parents fbd63c7 + a6c8513 commit 25bd7d8

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

lib/aggregate.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,23 @@ Aggregate.prototype.project = function(arg) {
392392
* @memberOf Aggregate
393393
* @instance
394394
* @param {Object} arg
395+
* @param {Object|Array<Number>} arg.near GeoJSON point or coordinates array
395396
* @return {Aggregate}
396397
* @api public
397398
*/
398399

399400
Aggregate.prototype.near = function(arg) {
401+
if (arg == null) {
402+
throw new MongooseError('Aggregate `near()` must be called with non-nullish argument');
403+
}
404+
if (arg.near == null) {
405+
throw new MongooseError('Aggregate `near()` argument must have a `near` property');
406+
}
407+
const coordinates = Array.isArray(arg.near) ? arg.near : arg.near.coordinates;
408+
if (typeof arg.near === 'object' && (!Array.isArray(coordinates) || coordinates.length < 2 || coordinates.find(c => typeof c !== 'number'))) {
409+
throw new MongooseError(`Aggregate \`near()\` argument has invalid coordinates, got "${coordinates}"`);
410+
}
411+
400412
const op = {};
401413
op.$geoNear = arg;
402414
return this.append(op);

test/aggregate.test.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,14 @@ describe('aggregate: ', function() {
287287
it('works', function() {
288288
const aggregate = new Aggregate();
289289

290-
assert.equal(aggregate.near({ a: 1 }), aggregate);
291-
assert.deepEqual(aggregate._pipeline, [{ $geoNear: { a: 1 } }]);
290+
assert.equal(aggregate.near({ near: { type: 'Point', coordinates: [1, 2] } }), aggregate);
291+
assert.deepEqual(aggregate._pipeline, [{ $geoNear: { near: { type: 'Point', coordinates: [1, 2] } } }]);
292292

293-
aggregate.near({ b: 2 });
294-
assert.deepEqual(aggregate._pipeline, [{ $geoNear: { a: 1 } }, { $geoNear: { b: 2 } }]);
293+
aggregate.near({ near: { type: 'Point', coordinates: [3, 4] } });
294+
assert.deepEqual(aggregate._pipeline, [
295+
{ $geoNear: { near: { type: 'Point', coordinates: [1, 2] } } },
296+
{ $geoNear: { near: { type: 'Point', coordinates: [3, 4] } } }
297+
]);
295298
});
296299

297300
it('works with discriminators (gh-3304)', function() {
@@ -308,19 +311,19 @@ describe('aggregate: ', function() {
308311

309312
aggregate._model = stub;
310313

311-
assert.equal(aggregate.near({ a: 1 }), aggregate);
314+
assert.equal(aggregate.near({ near: { type: 'Point', coordinates: [1, 2] } }), aggregate);
312315
// Run exec so we apply discriminator pipeline
313316
Aggregate._prepareDiscriminatorPipeline(aggregate._pipeline, stub.schema);
314317
assert.deepEqual(aggregate._pipeline,
315-
[{ $geoNear: { a: 1, query: { __t: 'subschema' } } }]);
318+
[{ $geoNear: { near: { type: 'Point', coordinates: [1, 2] }, query: { __t: 'subschema' } } }]);
316319

317320
aggregate = new Aggregate();
318321
aggregate._model = stub;
319322

320-
aggregate.near({ b: 2, query: { x: 1 } });
323+
aggregate.near({ near: { type: 'Point', coordinates: [3, 4] }, query: { x: 1 } });
321324
Aggregate._prepareDiscriminatorPipeline(aggregate._pipeline, stub.schema);
322325
assert.deepEqual(aggregate._pipeline,
323-
[{ $geoNear: { b: 2, query: { x: 1, __t: 'subschema' } } }]);
326+
[{ $geoNear: { near: { type: 'Point', coordinates: [3, 4] }, query: { x: 1, __t: 'subschema' } } }]);
324327
});
325328
});
326329

@@ -1284,4 +1287,17 @@ describe('aggregate: ', function() {
12841287
await p;
12851288
await m.disconnect();
12861289
});
1290+
1291+
it('throws error if calling near() with empty coordinates (gh-15188)', async function() {
1292+
const M = db.model('Test', new Schema({ loc: { type: [Number], index: '2d' } }));
1293+
assert.throws(() => {
1294+
const aggregate = new Aggregate([], M);
1295+
aggregate.near({
1296+
near: {
1297+
type: 'Point',
1298+
coordinates: []
1299+
}
1300+
});
1301+
}, /Aggregate `near\(\)` argument has invalid coordinates, got ""/);
1302+
});
12871303
});

0 commit comments

Comments
 (0)