我正在使用我的快递应用程序编写登录功能,并且不喜欢在回调链中有很多res.status(500).send(body)
重复的事实:
router.post('/login', (req, res) => {
User.findOne({
where: { username: req.body.username }
})
.then( user => {
if (user) {
User.verifyPassword(req.body.password, user)
.then((verified) => {
if (verified) {
let signedToken = jwt.sign(
{ user: user.id },
'secret',
{ expiresIn: 24 * 60 * 60 }
);
res.status(200).send({
token: signedToken,
userId: user.id,
username: user.username
});
} else {
// If password entered does not match user password
res.status(500).send({ error: true, });
}
})
// If bycrpt explodes
.catch((error) => {
res.status(500).send({ error: error, });
});
} else {
// If we can't even find a user with that username
res.status(500).send({ error: true, });
}
})
// If the db query to find a user explodes
.catch(error => {
res.status(500).send({ error: error });
});
});
其中两个与模糊的异常相关,这些异常会导致API爆炸。另外两个基于API返回的布尔值。 我不是一个后端工程师,这只是一个个人项目,但我想知道Node.js世界中最好的做法是什么。
虽然我们正在使用它,但我不确定在这些错误情况下发送的相应状态代码是什么,因为我确信500是不正确的。
答案 0 :(得分:0)
我会像这样重写你的代码,我们只有一个.catch
router.post('/login', (req, res) => {
User.findOne({ where: { username: req.body.username }})
.then(user => {
if (!user) // If we can't even find a user with that username
return Promise.reject(true); // You should probably return an Error
return User.verifyPassword(req.body.password, user)
})
.then((verified) => {
if (!verified) // If password entered does not match user password
return Promise.reject(true); // You should probably return an Error
let signedToken = jwt.sign({
user: user.id
},
'secret', {
expiresIn: 24 * 60 * 60
}
);
res.status(200).send({
token: signedToken,
userId: user.id,
username: user.username
});
}).catch(error => {
// If the db query to find a user explodes
// If we can't even find a user with that username
// If password entered does not match user password
// You could throw different errors and handle
// all of them differently here
res.status(500).send({
error: error
});
});
});
使用async/await
router.post('/login', async(req, res) => {
try {
const user = await User.findOne({ where: { username: req.body.username }});
if (!user) // If we can't even find a user with that username
throw new Error('Invalid username');
const verified = await User.verifyPassword(req.body.password, user)
if (!verified) // If password entered does not match user password
throw new Error('Invalid password');
let signedToken = jwt.sign({
user: user.id
},
'secret', {
expiresIn: 24 * 60 * 60
}
);
res.status(200).send({
token: signedToken,
userId: user.id,
username: user.username
});
} catch(error) {
// If the db query to find a user explodes
// If we can't even find a user with that username
// If password entered does not match user password
res.status(500).send({
error: error.message
});
}
});
关于状态代码,有多种方法可以处理它们,我通常会为每个状态代码抛出一个特定的错误。
<强> errors.js 强>
class Unauthorized extends Error {
constructor(message) {
super(message);
this.name = 'UnauthorizedError';
this.statusCode = 401
}
}
class BadRequest extends Error {
constructor(message) {
super(message);
this.name = 'BadRequestError';
this.statusCode = 400
}
}
/** more errors... **/
module.exports = {
Unauthorized,
BadRequest
};
所以我们现在可以设置正确的状态代码:
const { Unauthorized } = require('./errors');
/* ... */
try {
/* ... */
if (!verified) // Some people may say 422 status code...
throw new Unauthorized('Invalid password');
/* ... */
} catch(error) {
res.status(error.statusCode || 500).send({
error: error.message
});
}
虽然我们正在使用它,但我不确定适当的状态代码是什么 发送这些错误的情况将是,因为我确定500是不正确的。
你是对的,为每个错误设置500是不正确的。我会给你留下一些可能有助于你设置正确状态代码的问题,因为在这个问题上讨论它会太长。
What's an appropriate HTTP status code to return by a REST API service for a validation failure?