'Middleware swallows : E11000 duplicate key error collection

I am running in a very strange error from mongoDB.

I simply have the most basic set up here as an example of the bug:

https://github.com/leonardgable/test.git

Download the repo and try to create a user using a POST request with the route:

https://localhost:8000/api/v1/auth/signup

Once you create a user using an email address the user is created. But even though the mongoose schema says email : {

unique: true} it is possible to create another user with the same email. The user is then not created in the database but mongodb does not return the expected E11000 duplicate key error collection !!

If you comment the pre-save middleware in the user model then the code works as expected. The Mongodb return the error. so my question is the following:

WHY HAVING A PRE-SAVE MIDDLEWARE ON THE USER MODEL SWALLOWS THE Duplicate key error THAT WE ARE EXPECTING ?

To reproduce the error:

Comment the presave middleware in the user model Create a user using a post request on /api/v1/auth/signup with the email : [email protected]

Try to recreate a user with the same email >>>>> Duplicate key error: this time OK ! the code seems to work.

now try to uncomment the presave middleware in the user model

Try to recreate a user with the same email >>>> THE USER IS CREATED !!!! WHY ? NO DUPLICATE KEY ERROR ? Mongodb is expected to throw the error no ?

WHAT IS HAPPENING ? TAKE A LOOK AT https://github.com/leonardgable/test.git

If anyone can give me a straight answer on this I will be immensely grateful. I have been trying to figure this out for now 3 days .....

USER MODEL

const mongoose = require("mongoose");
const validator = require("validator");
 
// Create mongoose schema
const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: [true, "A Username is required"],
  },
  email: {
    type: String,
    required: [true, "Email is required"],
    unique: true,
    lowercase: true,
    validate: [validator.isEmail, "Please provide a valid email"],
  },
});
 
 
//COMMENT THE PRE SAVE MIDDLEWARE HERE !
userSchema.pre("save", async function (req, res, next) {
  console.log("USER PRE SAVE HOOK");
  next();
});
// Create the model
const User = mongoose.model("User", userSchema);
 
module.exports = User;

AUTHCONTROLLER

const User = require("./userModel");
 
/** User Sign up */
exports.signup = async (req, res, next) => {
  const newUser = await User.create({
    name: req.body.name,
    email: req.body.email,
    password: req.body.password,
    passwordConfirm: req.body.passwordConfirm,
  });
  console.log("USER SAVED");
  res.status(200).send({
    status: "success",
    data: { newUser },
  });
};

HERE ARE THE INDEXES FROM THE CONSOLE

`Atlas atlas-1ltehf-shard-0 [primary] viento-nomada> show collections
users
Atlas atlas-1ltehf-shard-0 [primary] viento-nomada> db.users.getIndexes()
[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  {
    v: 2,
    key: { email: 1 },
    name: 'email_1',
    background: true,
    unique: true
  }
]
Atlas atlas-1ltehf-shard-0 [primary] viento-nomada>


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source