gpt4 book ai didi

node.js - 在 express 发送错误时防止代码重复的最有效方法

转载 作者:太空宇宙 更新时间:2023-11-04 01:50:50 26 4
gpt4 key购买 nike

我正在使用我的 Express 应用程序编写登录函数,但不喜欢回调链中大量重复的 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 返回的 bool 值。我不是一个后端工程师,这只是一个个人项目,但我想知道 Node.js 世界中的最佳实践是什么。

当我们这样做时,我不确定在这些错误情况下发送的适当状态代码是什么,因为我确信 500 不正确。

最佳答案

我会像这样重写你的代码,其中我们只有一个.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
});

}

While we're at it, I'm not sure what the appropriate status code to send in these error cases would be, as I am sure 500 is not correct.

你是对的,为每个错误设置 500 是不正确的。我将留给您几个问题,可能会帮助您设置正确的状态代码,因为在这个问题中讨论它的时间太长了。

What's an appropriate HTTP status code to return by a REST API service for a validation failure?

What's the appropriate HTTP status code to return if a user tries logging in with an incorrect username / password, but correct format?

关于node.js - 在 express 发送错误时防止代码重复的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49744549/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com