Getting a error on aggregation method call

Hello:

I could use some assistance with methods. See the following which is a facsimle of client and server code I am using to call an aggregation method on the server. The code seems to work, but it throwing an error on the server console (see “Sample ERROR” below). There are not a large number of documents in the collection.

I am certained the more seasoned folks will spot the issue immediately. I’m sure it is the basic structure that needs fixing or the async nature of it is causing an issue.

Thanks

	//client
	Meteor.call('history.getCurrentHistory', nowPlusOneHour, (error, result) => {
		if(error){
			console.log("err: "+ error);
		}
		else{
			console.log("result: "+ result);
			//do other stuff
		}
	});

	//server
	'history.getCurrentHistory'(nowPlusOneHour){
		const cHistory = History.aggregate([
				{$project: { FIELDS_LIST: 1}},
				{$match: {$or: [
					{$and: [{ owner: { $eq: USERNAME } },
							{ datetime: {$gte: new Date(),$lte: new Date(nowPlusOneHour) }}]},
					{$and: [{ owner: { $eq: USERNAME } },
							{ datetime: {$lte: new Date()}},{ enddate: {$gte: new Date()}}]}]}},
				{$sort: { datetime: 1 }}
			])

		return cHistory;
	}

Sample ERROR

W20180819-13:52:44.397(-4)? (STDERR) (node:11360) UnhandledPromiseRejectionWarning: RangeError: Maximum call stack size exceeded
W20180819-13:52:44.400(-4)? (STDERR)     at Array.some (<anonymous>)
W20180819-13:52:44.402(-4)? (STDERR)     at Object.matchObject (packages/ejson/ejson.js:180:31)
W20180819-13:52:44.403(-4)? (STDERR)     at toJSONValueHelper (packages/ejson/ejson.js:239:19)
W20180819-13:52:44.407(-4)? (STDERR)     at Object.EJSON.toJSONValue.item [as toJSONValue] (packages/ejson/ejson.js:292:19)
W20180819-13:52:44.409(-4)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:188:29)
W20180819-13:52:44.410(-4)? (STDERR)     at Array.forEach (<anonymous>)
W20180819-13:52:44.414(-4)? (STDERR)     at Object.toJSONValue (packages/ejson/ejson.js:187:24)
W20180819-13:52:44.414(-4)? (STDERR)     at toJSONValueHelper (packages/ejson/ejson.js:240:24)
W20180819-13:52:44.417(-4)? (STDERR)     at Object.EJSON.toJSONValue.item [as toJSONValue] (packages/ejson/ejson.js:292:19)
W20180819-13:52:44.421(-4)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:188:29)
W20180819-13:52:44.421(-4)? (STDERR)     at Array.forEach (<anonymous>)
W20180819-13:52:44.423(-4)? (STDERR)     at Object.toJSONValue (packages/ejson/ejson.js:187:24)
W20180819-13:52:44.424(-4)? (STDERR)     at toJSONValueHelper (packages/ejson/ejson.js:240:24)
W20180819-13:52:44.425(-4)? (STDERR)     at Object.EJSON.toJSONValue.item [as toJSONValue] (packages/ejson/ejson.js:292:19)
W20180819-13:52:44.435(-4)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:188:29)
W20180819-13:52:44.436(-4)? (STDERR)     at Array.forEach (<anonymous>)
W20180819-13:52:44.439(-4)? (STDERR) (node:11360) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)
W20180819-13:52:44.441(-4)? (STDERR) (node:11360) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

History.rawCollection().aggregate().toArray()

Just to add to @rjdavid’s reply. As shown, that will return a Promise. Use async/await as follows:

async 'history.getCurrentHistory'(nowPlusOneHour) {
  const cHistory = await History.aggregate([
    { $project: { FIELDS_LIST: 1 } },
    {
      $match: {
        $or: [
          {
            $and: [{ owner: { $eq: USERNAME } },
            { datetime: { $gte: new Date(), $lte: new Date(nowPlusOneHour) } }]
          },
          {
            $and: [{ owner: { $eq: USERNAME } },
            { datetime: { $lte: new Date() } }, { enddate: { $gte: new Date() } }]
          }]
      }
    },
    { $sort: { datetime: 1 } }
  ]).toArray();

  return cHistory;
}
2 Likes

Good to know about this way of doing aggregate. You’ve posted this before but I’ve been used to using the rawCollection version. Are there any performance differences or anything to watch out about the differences?

Not that I know of.

Using async/await should be considered as the canonical way of working with the MongoDB npm package (which rawCollection() exposes). It’s easier to write and comprehend than callbacks or Promise chains and is more portable than Meteor.wrapAsync - which you could still use - but why would you, as Meteor’s async/await/Promise implementation is transparently Fibers aware?

1 Like

Thanks @rjdavid and @robfallows for your assistance. Your suggestions worked.

1 Like