I don't know what I'm missing but in the block catch session.abortTransaction() not rolling bak anything. I purposely used throw new Error("Error message") after the creation of a user to land in the catch block to trigger the session.abortTransaction() but when I look in the database I see that the user is still created despite the abortion.
Here is my source code
export const signUp = async (req, res) => {
const { email, password, fullname } = req.body;
// Init session
const session = await mongoose.startSession();
// Begin transaction
session.startTransaction();
try {
// Check if user exist in database using his email
const dbUser = await UserModel.findOne({ email }, null, session);
// Return a conflit code if user already exist
if (dbUser) return res.status(409).json({ message: "User already exists" });
// Create tenant
const tenantResult = await TenantModel.create([{ createdAt: new Date() }], null, session);
// Get admin role
const roleResult = await RoleModel.findById('626db17b8645717d657fc4c8', null, session);
//Hash password using jwt
const hashedPassword = await bcrypt.hash(password, 12);
// Store user in db
const userResult = await UserModel.create([
{
email: email,
password: hashedPassword,
fullname: fullname,
tenant: tenantResult[0],
role: roleResult
}
], null, session);
throw new Error("Error message");
if (userResult){
// Create subscription && currency
// Create currency for user
await CurrencyModel.create([
{
name: 'Dollar',
createdAt: new Date(),
symbol: '$',
isoCode: 'USD',
default: true,
userRole: 'setting-list',
createdBy: userResult[0],
}
], null, session);
}
// Generate token using jwt, secret, and user data
const token = jwt.sign( { email: userResult[0].email, id: userResult[0]._id }, secret, { expiresIn: "24h" } );
// Send welcome email to registered user
await sendWelcomeEmail(userResult[0].email, userResult[0].fullname, `Welcome ${userResult[0].fullname} - light-speed.dev`, 'welcome-email.html');
//Commit transaction
await session.commitTransaction();
// Return 201 Created http code with user and token
return res.status(201).json({ userResult, token });
} catch (error) {
// Abort transaction if one of these request throw error
await session.abortTransaction();
console.log(error);
return res.status(400).json({ message: 'Something went wrong!' });
} finally {
// close session
session.endSession();
}
};
Thank you for your help!
CodePudding user response:
I finally figured out why the session doesn't roll back transactions. It's because of the way I specify the session option.
I change these lines
const dbUser = await UserModel.findOne({ email }).session(session);
const tenantResult = await TenantModel.create([{ createdAt: new Date() }], { session: session });
const roleResult = await RoleModel.findById('626db17b8645717d657fc4c8').session(session);
const userResult = await UserModel.create([
{
email: email,
password: hashedPassword,
fullname: fullname,
tenant: tenantResult[0],
role: roleResult
}
], { session: session });
await CurrencyModel.create([
{
name: 'Dollar',
createdAt: new Date(),
symbol: '$',
isoCode: 'USD',
default: true,
userRole: 'setting-list',
createdBy: userResult[0],
}
], { session: session });