MongoDB findOne查询命中数据仍进入错误分支解决方案
问题原因
你的代码存在两个核心错误,直接导致逻辑分支走错:
- 混用Mongoose回调模式与Promise async/await模式:
User.findOne()如果不传回调,会返回Promise对象,此时走Promise链式调用规范——.then()的第一个入参永远是异步操作成功的返回结果,错误只会进入.catch()分支,根本不会把错误传给.then()的回调。 - 形参映射完全错误:你写的
.then(function (err, user)),会把查询到的用户对象直接赋值给第一个形参err,第二个形参user始终为undefined,自然会出现「打印err拿到正常用户数据、误进入错误分支」的现象,和你猜测的回调参数顺序无关,是用法本身不符合Promise规范。
另外你的代码还有两个隐性问题:
- 查询条件硬编码为
sab2,没有使用传入的参数uName - async函数内没有返回Promise链的执行结果,外部调用
validateUsername时拿不到你预期的布尔返回值
控制台打印结果参考:
修复方案
推荐使用纯async/await写法,逻辑清晰不易出错:
exports.validateUsername = async (uName) => { console.log("inside validate username"); try { // 注意替换硬编码的查询值为入参uName const user = await User.findOne({ username: uName }); if (user) { console.log("inside user found"); console.log("user"); console.log(user); return false; // 用户名已存在,校验不通过 } return true; // 用户名未占用,校验通过 } catch (err) { console.log("inside err"); console.log("error"); console.log(err); // 可根据业务需求调整错误场景的返回值 throw err; } };
如果要使用Promise链式写法,不要额外套async/await,记得补全错误捕获:
exports.validateUsername = (uName) => { console.log("inside validate username"); return User.findOne({ username: uName }) .then(user => { if (user) { console.log("inside user found"); console.log("user"); console.log(user); return false; } return true; }) .catch(err => { console.log("inside err"); console.log("error"); console.log(err); throw err; }); };
避坑提示
- Mongoose异步操作不要同时混用回调写法和Promise写法,二选一即可
- Promise的
.then()回调仅接收成功结果,错误必须通过.catch()或async/await的try/catch捕获
内容的提问来源于stack exchange,提问作者sabari
相关产品推荐
相关产品推荐

