登录接口异常:MySQL无对应邮箱时抛出password未定义TypeError
登录API遇不存在邮箱时报错的解决方案
你遇到的问题是:当使用MySQL数据库中不存在的邮箱请求登录API时,服务端抛出TypeError: Cannot read property 'password' of undefined错误,但邮箱存在时能正常运行。
报错信息
Error: S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\Parser.js:437 throw err; // Rethrow non-MySQL errors ^ TypeError: Cannot read property 'password' of undefined at Query.db.query (S:\#development\Pepperkart\pepperkart-backend\routes\users.js:19:43) at Query.<anonymous> (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\Connection.js:525:10) at Query._callback (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\Connection.js:491:16) at Query.Sequence.end (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24) at Query._handleFinalResultPacket (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\sequences\Query.js:139:8) at Query.EofPacket (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\sequences\Query.js:123:8) at Protocol._parsePacket (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\Protocol.js:291:23) at Parser._parsePacket (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\Parser.js:433:10) at Parser.write (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\Parser.js:43:10) at Protocol.write (S:\#development\Pepperkart\pepperkart-backend\node_modules\mysql\lib\protocol\Protocol.js:38:16) [nodemon] app crashed - waiting for file changes before starting...
你的登录API代码
router.post('/login', (req, res) => { var email = req.body.email var password = req.body.password var GRAB_USER = `SELECT * FROM user_details WHERE email = ?` db.query(GRAB_USER, email, (err, result) => { if (err) { res.send('email not found') } else { var user = result[0] bcrypt.compare(password, user.password, (err, match) => { if (err) { res.send('password not match') } else { res.send(user) } }); } }) })
错误原因分析
这个问题的核心是你混淆了数据库查询错误和查询无结果的情况:
- 当邮箱不存在时,MySQL的查询操作本身没有出错(
err为null),所以代码会进入else分支。 - 但此时查询返回的
result是一个空数组,result[0]自然就是undefined,你接着尝试访问user.password就触发了TypeError。
修复方案
你需要在else分支里先检查查询结果是否为空,也就是判断result.length === 0,如果为空就返回邮箱不存在的提示,再执行后续的密码验证逻辑。修改后的代码如下:
router.post('/login', (req, res) => { var email = req.body.email; var password = req.body.password; var GRAB_USER = `SELECT * FROM user_details WHERE email = ?`; db.query(GRAB_USER, email, (err, result) => { if (err) { // 这里处理数据库查询本身的错误,比如连接问题等 res.status(500).send('服务器内部错误'); return; } // 检查是否查询到用户 if (result.length === 0) { res.status(400).send('邮箱未找到'); return; } var user = result[0]; bcrypt.compare(password, user.password, (err, match) => { if (err) { res.status(500).send('密码验证失败'); return; } if (!match) { res.status(400).send('密码不匹配'); return; } res.send(user); }); }); })
额外优化建议
- 给响应加上合适的HTTP状态码(比如400表示客户端错误,500表示服务端错误),这样前端能更准确判断错误类型。
- 区分数据库查询错误和业务逻辑错误(比如邮箱不存在、密码不匹配),不要把所有错误都归为“email not found”。
内容的提问来源于stack exchange,提问作者devbeans
相关产品推荐
相关产品推荐

