简体   繁体   English

在 NodeJS 中抛出错误 - UnhandledPromiseRejection

[英]Throwing errors in NodeJS - UnhandledPromiseRejection

I'm pretty new on NodeJS and I'm still trying to figure out how to handle errors.我对 NodeJS 还很陌生,我仍在努力弄清楚如何处理错误。 I read a lot of questions but I don't realize what I'm doing wrong.我阅读了很多问题,但我没有意识到我做错了什么。

Here I have a login function:这里我有一个登录功能:

export const login = async (req, res) => {
let body = req.body;

try {
  const user = await User.findOne({ username: body.username });

if (!user) {
  throw new InternalError("Username or password are wrong");
}

if (!bcrypt.compareSync(body.password, user.password)) {
  throw new InternalError("Username or password are wrong");
}

let token = jwt.sign({ data: user }, "secret", {
  expiresIn: 60 * 60 * 24 * 30
});

return res.json({
  user: user,
  token: token
 });
} catch (error) {
throw new GenericError(error);
 }
};

And this is the error I get if, for example, I include a wrong password:这就是我得到的错误,例如,我输入了错误的密码:

(node:12332) UnhandledPromiseRejectionWarning: GenericError: Username or password are wrong
(node:12332) 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()

I know the promises made with Await must have a .then() and .catch() but this is not an error on executing the promise but on validating the password.我知道用.catch()做出的承诺必须有.catch() .then().catch()但这不是执行承诺时的错误,而是验证密码时的错误。 What I want is to throw the error and get the response.我想要的是抛出错误并获得响应。 Right now the request never ends and the previous error is displayed.现在请求永远不会结束并显示上一个错误。

Thank you!谢谢!

PS: InternalError and GenericError are just errors created by me which extends from Error PS:InternalError 和 GenericError 只是我创建的从 Error 扩展而来的错误

You receive the warning from node because you are re-throwing a GenericError after catching InternalError.您收到来自节点的警告,因为您在捕获 InternalError 后重新抛出 GenericError。 Instead of re-throwing the GenericError, you should return your response or catch your GenericError when calling login .您应该在调用login时返回您的响应或捕获您的 GenericError 而不是重新抛出 GenericError 。

Here is your code modified for both.这是您为两者修改的代码。

export const login = async (req, res) => {
  // We get the body info
  let body = req.body;

  try {
    // We find the user with the username from the body
    const user = await User.findOne({ username: body.username });

    // Let's assume no user exists, so we throw an InternalError,
    // This skips straight to the catch block.
    if (!user) {
      throw new InternalError("Username or password are wrong");
    }

    // We never reach these two statements
    // because of the error above being thrown.
    if (!bcrypt.compareSync(body.password, user.password)) {
      throw new InternalError("Username or password are wrong");
    }

    let token = jwt.sign({ data: user }, "secret", {
      expiresIn: 60 * 60 * 24 * 30
    });

   res.json({
      user: user,
      token: token
    });
  } catch (err) {
    // We caught our InternalError from not having a user above.
    // Now we should return a response that the user is invalid.
    // I am just going to return the error that we previously threw.
   res.json({
      error: err
    });
  }
};

You can definitely throw the GenericError from your catch block.您绝对可以从 catch 块中抛出 GenericError 。 However, doing that then requires you to catch the GenericError wherever you are calling your login function.但是,这样做需要您在调用登录函数的任何地方捕获 GenericError。

export const login = async (req, res) => {
  // We get the body info
  let body = req.body;

  try {
    // We find the user with the username from the body
    const user = await User.findOne({ username: body.username });

    // Let's assume no user exists, so we throw an InternalError,
    // This skips straight to the catch block.
    if (!user) {
      throw new InternalError("Username or password are wrong");
    }

    // We never reach these two statements
    // because of the error above being thrown.
    if (!bcrypt.compareSync(body.password, user.password)) {
      throw new InternalError("Username or password are wrong");
    }

    let token = jwt.sign({ data: user }, "secret", {
      expiresIn: 60 * 60 * 24 * 30
    });

   res.json({
      user: user,
      token: token
    });
  } catch (err) {
    // Throw the generic error
    throw GenericError(err);
  }
};


try {
  // We call the login function that is defined above.
  // It is going to throw a GenericError, so we have to
  // catch it.
  await login(req, res);
} catch (err) {
  // Now we need to catch the generic error
  res.json({
    error: err
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 抛出错误 UnhandledPromiseRejection 后,NodeJS 程序未退出 - NodeJS program is not exiting after throwing an error UnhandledPromiseRejection 使用 nodejs 和 mongodb 的 UnhandledPromiseRejection 问题 - UnhandledPromiseRejection problem with using nodejs and mongodb 即使包裹在 try catch 中的代码也会抛出 UnhandledPromiseRejection - throwing UnhandledPromiseRejection even the code wrapped in try catch 在其他地方处理尝试/捕获的 promise 上调用.finally 会导致 nodejs 中的 UnhandledPromiseRejection - Calling .finally on a promise that is try/catch handled elsewhere causes UnhandledPromiseRejection in nodejs NodeJS & React w/ DevExpress - 导入变量抛出语法错误 - NodeJS & React w/ DevExpress - import variable throwing syntax errors 开玩笑:卡在 [UnhandledPromiseRejection:此错误源于在没有 catch 块的情况下抛出异步 function 内部, - Jest: stuck on [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, eslint 在没有错误的地方抛出错误 - eslint throwing errors where there are no errors JavaScript函数抛出错误 - Javascript function throwing errors 抛出字符串而不是错误 - Throwing strings instead of Errors 危险地SetInnerHTML 抛出意外错误 - dangerouslySetInnerHTML Throwing Unexpected Errors
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM