【发布时间】:2019-11-18 15:02:01
【问题描述】:
我确定这是一个新手问题,但我现在才尝试学习 express/node/react 一个月左右。
我只是想进行一个简单的节点登录 REST API 调用。这是一段代码,为了简洁起见,对不重要的部分进行了一些“伪化”:
server.post('/signin', (request, response) => {
const {user_email, password} = request.body
// query db for user validation
db('user_login')
/* knex query building, blah blah blah */
.then(res => {
if (res.length == 0) {
// if res.length == 0, user not found
throw new Error("bad credentials")
} else if (res.length > 1) {
// if res.length > 1, duplicate user found - shouldn't ever happen
throw new Error("CRITICAL: database error")
} else {
// everything should be ok - pass res on to bcrypt
return res
}
})
.then(res => {
// bcrypt.compare doesn't return a promise because it is being given a cb
bcrypt.compare(password, res[0].pw_hash, (err, match) => {
if (match) {
// delete pw_hash from any possible response(),
// don't give client more info than it needs
delete res[0].pw_hash
// we have a match! inform the client
response.json(res[0])
} else {
// we don't have a match
throw new Error("bad credentials") // WHY DOES THIS THROW CRASH!??!?!!?!?
}
})
})
// WHY ISNT THIS REACHED WHEN THERE'S A PASSWORD MISMATCH?
.catch(err => {
console.error('signin error: ', err)
response.status(403).json({
name: err.message,
severity: 'auth error',
code: 403
})
})
})
好的:
- 当提供正确的用户名和密码时,它会按预期运行。
- 当提供的用户名不正确时,会到达 .catch(即按预期运行)。
- 但是:当提供正确的用户名和 incorrect 密码时,throw 语句(带有注释 // WHY DOES THROW CRASH?)... 使节点崩溃。
这是调用堆栈:
C:\.............\server.js:83
throw new Error("bad credentials") // WHY DOES THIS THROW CRASH!??!?!!?!?
^
Error: bad credentials
at C:\.............\server.js:83:23
at C:\.............\node_modules\bcrypt-nodejs\bCrypt.js:689:3
at processTicksAndRejections (internal/process/task_queues.js:75:11)
[nodemon] app crashed - waiting for file changes before starting...
我可以“作弊”,然后做一个 response.status(403).... 而不是那个投掷。但在我看来,抛出该错误应该跳转到 .catch,并在那里处理任何身份验证失败。
谁能帮我看看这里发生了什么?这很令人沮丧。
附言。只有当 throw 在 bcrypt.compare 回调中时才会发生这种崩溃。我认为这与它有关。我用谷歌搜索了..我在这里环顾四周..我已经将东西包装在 try/catch 块中。在这一点上,我只是在反对它。
谢谢! :)
【问题讨论】:
-
好的,在查看 bcrypt.compare 的代码后,我只能假设这是因为 bcrypt.compare 通过 process.nextTick 调用 compareSync。所以 throw 与所有其余的 Promise 不在同一个“链”上。我仍在努力寻找解决方法
标签: node.js asynchronous concurrency promise bcrypt