Meteor 3: Cursor.forEach() on server should report an error

Just wanted to drop a note for a potential pitfall when upgrading to Meteor 3:

I had two occurrences where I unintentionally forgot to do a fetch() on a cursor before calling forEach() on the result, like in this example:

const users = Meteor.users.find();
users.forEach(user => ...)

This actually calls forEach() on the cursor instead of a document array, which worked just fine on Meteor 2, so I never noticed this.

On Meteor 3, however, a Cursor.forEach() call does not work on the server, only Cursor.forEachAsync() iterates on the cursor. There is no warning or error about this, though. Cursor.forEach() just fails silently, always returning an empty array.

I think it would be good if Meteor 3 would report an error for Cursor.forEach() if used on the server, as it does for other deprecated sync methods.

We also encountered this when moving to async. It would be great if Meteor could help catch this error because the eslint route was tricky to implement.

Our solution is to use custom eslint to identify the errors explicitly but a forced lint is required to cover the entire codebase. It was very tricky because the cursor could be returned from a function. The eslint rules must cover a wide possibility of use cases (short of creating a tslint rule instead). We ended up focusing on our use case (how we code and structure our files).

1 Like

I think Meteor 3 designed to do so and adding warning or error to Mongo.Cursor is not a good solution.
What if you want to work with those cursors instead of documents? you have to deal with those warning/error all the time while Meteor 3 has all Async apis.
I know it’s painful migrating from none Async (Meteor 2) to Async (Meteor 3) but we have to adapt.
Eslint is not good enough tool but Typescript helps a lot.

The error handling should be added on the cursor methods and not on the cursor itself

Yes, I understand, add to cursor’s forEach method for example. But what if you really want to work with forEach method? I don’t see anything wrong if you call Cursor.forEach() knowing that you’re working with cursors, not documents.

Maybe I was not clear enough: On Meteor 3, this Cursor.forEach() actually does nothing at all on the server, it just returns an empty array. On the client, it might work (haven’t tested it). So I am not saying that they should place a warning for calls that work, but for those that don’t (i.e., on the server). In our case, the silently failing call broke a feature and I only noticed this when hand-testing our whole app after the Meteor 3 upgrade.

I apology. I’ve checked documents, the forEach function without Async word but it is a real async function. It could lead to some unexpected behaviors.

1 Like