为用户身份验证nodejs抛出错误时的错误处理



我已经设置了一个用于错误处理的中间件:

//errorMiddleware.js
export const notFound = (req, res, next) => {
const error = new Error(`Not Found - ${req.originalUrl}`);
res.status(404);
next(error);
};
export const errorHandler = (err, req, res, next) => {
res.status(err.status || 500);
res.json({
errors: { message: err.message },
});
};

例如,我尝试编写API来验证用户。当用户输入错误的电子邮件或密码时,我会抛出一个错误:

const { email, password } = req.body;
const user = await User.findOne({ email });
if (user && (await user.comparePassword(password))) {
res.json({
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin,
token: generateToken(user._id),
});
} else {
res.status(401);
throw new Error("Invalid email or password");
}

然而,我使用邮递员来测试请求,这会导致错误,并且不会发送我在上面设置的任何响应:

(node:15900) UnhandledPromiseRejectionWarning: Error: Invalid email or password
at authUser (file:///D:/Practice%20Web/MERN/eCommerce/backend/controllers/userController.js:20:11)       
at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:15900) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)        
(node:15900) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我该如何处理那个问题。提前感谢!

这里有几件事需要理解。

  1. 异步代码(等待(应该始终在try-and-catch块中,或者父级具有catch块,无论哪种方式,您都应该始终尝试在某个地方捕获它。为了不再出现未处理的错误。

  2. 失败/抛出错误的函数是user.comparePassword(password)函数。因为这里没有try-catch块,所以该函数会抛出错误,节点不知道该怎么处理它

  3. 由于您有一个错误处理程序来处理路由/函数中的错误,因此您应该尝试捕获所有可能的错误,并将其传递给下一个函数。

try {
if (
user is not valid
) {
throw new Error('Your error', 401);
}
// do some other stuff
res.json(results)
} catch (err) {
next(err);
}
  1. 请注意,您可以将状态号传递给error,这将传递给res.status(err.status || 500);
  2. 另一件需要记住的事情是小心res.send,一旦这样做,就会发送响应,所有其他子res.send调用都会导致类型错误。因此,您必须确保错误处理程序为您发送错误,而不是您正在调用的函数

最新更新