ClientSession cannot be serialized to BSON
Asked Answered
C

2

8

Hello i've been trying to implement transanctions to my crud operations on my mongodb atlas using mongoose, i have tried to look up for tutorials and stuff, but there really aren't that many around, i have this problem of "ClientSession cannot be serialized to BSON" after i try to hit a user create route, my code:

router.post(
'/',
[
check('name', 'Por favor, ingresar el nombre')
  .not()
  .isEmpty(),
check('email', 'Por favor, ingresar un correo válido').isEmail(),
check(
  'password',
  'Por favor, ingresar una contraseña con 6 o más carácteres'
).isLength({ min: 6 })
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
  return res.status(400).json({ errors: errors.array() });
}

    const { name, email, password, imagen } = req.body;

    const session = await User.startSession() // Las transacciones usan sesiones
    // const session = await mongoose.startSession() // Las transacciones usan sesiones
    session.startTransaction()  // Empezar una transacción

try {

    const opts = {session} // Opciones de consulta del modelo

  const user = await User.findOne({ email }, opts ); // Enviar opts para usar transac

  if (user) {
    return res
      .status(400)
      .json({ errors: [{ msg: 'Ya existe una cuenta creada con este correo' }] });
        }

  user = new User({
    name,
    email,
            password,
            imagen
  });

  const salt = await bcrypt.genSalt(10);

  user.password = await bcrypt.hash(password, salt);

  await user.save(opts);

  const payload = {
    user: {
      id: user.id
    }
  };

  jwt.sign(
    payload,
    config.get('jwtSecret'),
    { expiresIn: 360000 },  // Cambiar a 3600 en producción 3600s = 1 hora
    (err, token) => {
      if (err) throw err;
      res.json({ token });
    }
        );

        await session.commitTransaction(); // Commit de la transacción
  session.endSession(); // Terminar la sesión
  return true
} catch (err) {

        await session.abortTransaction(); // Abortar o rollback de la transacción
        session.endSession(); // Terminar la sesión
  console.error(err.message);
  res.status(500).send('Error del servidor');
}});

So, im not really sure what this means, i would really like to know what are the basic steps into mongoose transactions to kind of grasp the main concept, thanks.

Casady answered 23/12, 2019 at 21:17 Comment(0)
D
19

I had the same issue. So try to replace

const user = await User.findOne({ email }, opts );

with that:

const user = await User.findOne({ email }, null, opts );

it solved my problem :)

Desdee answered 19/4, 2020 at 12:25 Comment(2)
explanation: github.com/Automattic/mongoose/issues/6663Decode
User.findOne({ email }, opts).session(session) also worksDecode
B
3

I know this is an old question but I had to face the same scenario and here is how I overcame that challenge. This information may be helpful.

The issue is that the 2nd arg to Model.findOne() is always a projection. It would work if you did like this,

await A.findOne({}, null, { session });

here is an example of code snippets

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017,localhost:27018,localhost:27019/gh-6663?replicaSet=rs');
const conn = mongoose.connection;
const Schema = mongoose.Schema;

const schemaA = new Schema({
  name: String
});

const schemaB = new Schema({
  name: String
});

const A = mongoose.model('A', schemaA);
const B = mongoose.model('B', schemaB);

const a = new A({ name: 'Andrew' });
const b = new B({ name: 'Billy' });

async function run() {
  await conn.dropDatabase();
  await a.save();
  await b.save();

  const session = await A.startSession();
  await session.startTransaction();
  const foundA = await A.findOne({}, {}, { session });
  await B.findOneAndUpdate({}, { name: foundA.name }, { session });

  await session.commitTransaction();
  session.endSession();

  let newB = await B.findOne({});
  console.log(`hello from ${newB.name}`);
  return conn.close();
}

run().catch(console.error)

source : mongoose GitHub issue

Burgomaster answered 29/10, 2022 at 6:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.