MERN项目中Mongoose事务创建Seller与User时的budget验证错误
解决Mongoose事务创建Seller和User时的预算字段验证错误
核心问题:参数传递顺序完全颠倒
控制器调用服务函数时,把seller和user的参数顺序搞反了。服务函数定义的是createSeller(user: IUser, seller: ISeller),但控制器里传的是createSeller(seller, data),导致创建Seller时用的是User的数据(根本不含budget字段),直接触发了Seller模型的必填字段验证报错。
修复步骤
1. 修正控制器的参数顺序
把控制器里的服务调用改为正确的参数顺序:
const result = await UserService.createSeller(data, seller);
2. 修正create返回值的判断逻辑
Model.create()传入单个对象时,返回的是单个文档而非数组,原代码里!newSeller.length的判断完全无效,改成直接判断文档是否存在:
// 创建Seller的判断 const newSeller = await Seller.create(seller, { session }); if (!newSeller) { throw new ApiError(status.BAD_REQUEST, 'Failed to create Seller'); } // 创建User的判断同理 const newUser = await User.create(user, { session }); if (!newUser) { throw new ApiError(status.BAD_REQUEST, 'Failed to create User'); }
3. 修正User查询的条件
最后查询User时,用_id而非id,或者直接用findById更简洁:
newUserAllData = await User.findById(newUserAllData._id).populate({ path: 'seller', });
修正后的关键代码片段
修正后的控制器代码
const createSeller:RequestHandler = catchAsync(async (req: Request, res: Response) => { const {seller, ...data } = req.body; // 交换参数顺序,把user数据放前面,seller数据放后面 const result = await UserService.createSeller(data, seller); console.log(result, 'here is the logger information about result') sendResponse<IUser>(res, { statusCode:status.OK , success: true, message: "Successfully user has been created", data: result, }); console.log(data, 'line number 20 controller') })
修正后的服务代码片段
const createSeller = async (user: IUser, seller: ISeller): Promise<IUser | null> => { console.log(seller,user, 'line number 11') user.role = 'seller'; let newUserAllData = null; const session = await mongoose.startSession(); try { session.startTransaction(); const newSeller = await Seller.create(seller, { session }); if (!newSeller) { throw new ApiError(status.BAD_REQUEST, 'Failed to create Seller'); } user.seller = newSeller._id; // 直接取单个文档的_id,不用[0] console.log(user.seller, 'user.seller') const newUser = await User.create(user, { session }); if (!newUser) { throw new ApiError(status.BAD_REQUEST, 'Failed to create User'); } newUserAllData = newUser; console.log(newUserAllData) await session.commitTransaction(); await session.endSession(); } catch (error) { await session.abortTransaction(); await session.endSession(); console.log(error, 'serice error from catch and throw') throw error; } console.log(newUserAllData, 'service line 47') if (newUserAllData) { newUserAllData = await User.findById(newUserAllData._id).populate({ path: 'seller', }) } console.log('new user all data from user service',newUserAllData) return newUserAllData; }
内容的提问来源于stack exchange,提问作者mohammad biplob
相关产品推荐
相关产品推荐

