Skip to content

Bug: TypeError: Cannot set property 'eachAsync' of undefine #5145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
CarlosGRodriguezL opened this issue Apr 3, 2017 · 2 comments
Closed
Milestone

Comments

@CarlosGRodriguezL
Copy link

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
This just fails sometimes, when the model.collection.aggregate returns null or undefined.
In the decorateCursor the aggregate.js trys to add the eachAsync function, but as it is undefinde it crashes.

Aggregate.prototype.exec = function(callback) {
  ...
    var cursor = this._model.collection.
      aggregate(this._pipeline, this.options || {});
    decorateCursor(cursor);
    return cursor;
  ...
  return new Promise.ES6(function(resolve, reject) { ... });
};
function decorateCursor(cursor) {
  cursor.eachAsync = function(fn, callback) { ... };
}

What is the expected behavior?

It should wait till the aggregate is finished or check if the cursur is undefined and return a understandable exception.

Please mention your node.js, mongoose and MongoDB version.
mongoose version: 4.8.6
nodejs version: 6.9.x

@vkarpov15
Copy link
Collaborator

Confirmed. This issue will only happen if mongoose is not connected to mongodb.

Repro:

var Schema = mongoose.Schema;

mongoose.set('debug', true);

mongoose.connect('mongodb://localhost:27017/gh5145');

var schema = new Schema({});
var M = mongoose.model('Test', schema);

M.aggregate([{ $match: { name: 'test' } }]).cursor().exec().eachAsync(() => {}).then(res => console.log(res));

To work around this, wait for mongoose to connect:

var Schema = mongoose.Schema;

mongoose.set('debug', true);

mongoose.connect('mongodb://localhost:27017/gh5145').then(() => {
  var schema = new Schema({});
  var M = mongoose.model('Test', schema);

  M.aggregate([{ $match: { name: 'test' } }]).cursor().exec().eachAsync(() => {}).then(res => console.log(res));
});

Or use the async option for aggregation cursors:

var Schema = mongoose.Schema;

mongoose.set('debug', true);

mongoose.connect('mongodb://localhost:27017/gh5145');

var schema = new Schema({});
var M = mongoose.model('Test', schema);

M.aggregate([{ $match: { name: 'test' } }]).cursor({ async: true }).exec(function(error, cursor) {
  cursor.eachAsync(() => {}).then(res => console.log(res));
});

@vkarpov15 vkarpov15 added this to the 4.9.5 milestone Apr 11, 2017
@vkarpov15 vkarpov15 modified the milestones: 4.10, 4.9.5 Apr 11, 2017
@vkarpov15
Copy link
Collaborator

In 4.10 we'll add a special flag useMongooseAggCursor that will let you do M.aggregate([{ $match: { name: 'test' } }]).cursor({ useMongooseAggCursor: true }).eachAsync() without waiting for mongoose to connect 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants