Skip to content
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

"insertOne" callback gets called twice on error. #10956

Closed
neil-hardlight opened this issue Nov 4, 2021 · 4 comments
Closed

"insertOne" callback gets called twice on error. #10956

neil-hardlight opened this issue Nov 4, 2021 · 4 comments
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@neil-hardlight
Copy link

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

What is the current behavior?
"insertOne" callback gets called twice on error. Although I suspect the bug affects all collection APIs.

If the current behavior is a bug, please provide the steps to reproduce.
Call "insertOne" after disconnecting from the database to force an error. Notice that the callback gets called twice.

model.collection.insertOne(newModel, dbOptions, (err, result) => {
    if (err) {
        return next(err); <-- GETS CALLED TWICE
    }

I have isolated the issue to here:

drivers\node-mongodb-native\collection.js

Line 214:

} catch (error) {
    // Collection operation may throw because of max bson size, catch it here
    // See gh-3906
    if (typeof callback === 'function') {
        callback(error); <-- THIS SHOULD RETURN
    } else {
        this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, error: error });
    }
    if (typeof lastArg === 'function') {
        lastArg(error); <-- THIS CALLS THE CB AGAIN
    } else {
        throw error;
    }
}

Higher up the file (line 162) you can see that the "callback" already calls "lastArg":

callback = function collectionOperationCallback(err, res) {
    if (err != null) {
        _this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: _this.name, method: i, error: err });
    } else {
        _this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: _this.name, method: i, result: res });
    }
    return lastArg.apply(this, arguments); <-- ALREADY CALLS LASTARG
};

What is the expected behavior?
Callback only gets called once.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
Mongoose 6.0.12
Node 14.17.0

@IslandRhythms
Copy link
Collaborator

ReferenceError: next is not defined

@IslandRhythms IslandRhythms added the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label Nov 8, 2021
@neil-hardlight
Copy link
Author

model.collection.insertOne(newModel, dbOptions, (err, result) => {
    if (err) {
        return next(err); <-- GETS CALLED TWICE
    }

This is not a complete code sample - it's a fragment. I'm just showing that on-error, the callback from "insertOne" is called twice. I can simplify it to:

model.collection.insertOne(newModel, dbOptions, (err, result) => {
    if (err) {
        console.log('This log message will be displayed twice');
    }

Does that help with clarifying the problem?

@IslandRhythms IslandRhythms added confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity labels Nov 8, 2021
@IslandRhythms
Copy link
Collaborator

const mongoose = require('mongoose');

const testSchema = new mongoose.Schema({
    name: String
});

const Test = mongoose.model('Test', testSchema);
const OtherModel = mongoose.model('OtherModel', testSchema);

async function test() {
    await mongoose.connect('mongodb://localhost:27017/', {useNewUrlParser: true,
    useUnifiedTopology: true,});
    await mongoose.connection.dropDatabase();
    await Test.create({ name: 'Daniel '});
    mongoose.connection.close();
    mongoose.connection.on('disconnected', () => {
        Test.collection.insertOne(OtherModel, {}, (err, result) => {
            if(err) return console.log('should show twice');
        });
    });
}

mongoose.connection.on('open', () => {
    console.log('open fire');
});

mongoose.connection.on('connected', () => {
    console.log('connected successfully');
});

test();

@neil-hardlight
Copy link
Author

Thank you for your code sample - as you can see, it behaves as I described:

connected successfully
open fire
should show twice
should show twice

@vkarpov15 vkarpov15 added this to the 6.0.16 milestone Nov 11, 2021
@vkarpov15 vkarpov15 modified the milestones: 6.0.16, 6.0.15 Dec 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Projects
None yet
Development

No branches or pull requests

3 participants