UnhandledPromiseRejectionWarning:此错误是由于在没有 catch 块的情况下抛出异步函数而引起的

问题描述 投票:0回答:6

我的 Node-Express 应用程序中出现以下错误

UnhandledPromiseRejectionWarning:未处理的承诺拒绝。这 错误是通过抛出异步函数内部而产生的 没有 catch 块,或者拒绝未处理的承诺 与.catch()。 (拒绝编号:4)

至少可以说,我创建了一个看起来像这样的辅助函数

const getEmails = (userID, targettedEndpoint, headerAccessToken) => {
    return axios.get(base_url + userID + targettedEndpoint,  { headers: {"Authorization" : `Bearer ${headerAccessToken}`} })
    .catch(error => { throw error})
}

然后我导入这个辅助函数

const gmaiLHelper = require("./../helper/gmail_helper")

并像这样在我的 api 路由中调用它

router.get("/emailfetch", authCheck, async (req, res) => {
  //listing messages in users mailbox 
  let emailFetch = await gmaiLHelper.getEmails(req.user._doc.profile_id , '/messages', req.user.accessToken)
  .catch(error => { throw error})
  emailFetch = emailFetch.data
  res.send(emailFetch)
})

从我的角度来看,我认为我正在通过使用 catch 块来处理错误。

问题:有人可以解释一下为什么我收到错误以及如何修复它吗?

javascript node.js express
6个回答
53
投票

.catch(error => { throw error})
是一个空操作。这会导致路由处理程序中未处理的拒绝。

正如这个答案中所解释的,Express不支持承诺,所有拒绝都应该手动处理:

router.get("/emailfetch", authCheck, async (req, res, next) => {
  try {
  //listing messages in users mailbox 
    let emailFetch = await gmaiLHelper.getEmails(req.user._doc.profile_id , '/messages', req.user.accessToken)
    emailFetch = emailFetch.data
    res.send(emailFetch)
  } catch (err) {
    next(err);
  }
})

15
投票

我建议从 getMails 中删除以下代码

 .catch(error => { throw error})

在你的主函数中,你应该将await和相关代码放在Try块中,并在失败代码处添加一个catch块。


您的函数 gmaiLHelper.getEmails 应该返回一个包含拒绝和解析的承诺。

现在,在调用和使用await时,将其放入try catch块中(删除.catch),如下所示。

router.get("/emailfetch", authCheck, async (req, res) => {
  //listing messages in users mailbox 
try{
  let emailFetch = await gmaiLHelper.getEmails(req.user._doc.profile_id , '/messages', req.user.accessToken)
}
catch (error) { 
 // your catch block code goes here
})

6
投票

您捕获了错误,但随后又重新抛出它。您应该尝试更优雅地处理它,否则您的用户将看到 500、内部服务器错误。

您可能想发回一个响应,告诉用户出了什么问题,并在您的服务器上记录错误。

我不确定请求可能返回什么错误,您可能想要返回类似的内容。

router.get("/emailfetch", authCheck, async (req, res) => {
  try {
    let emailFetch = await gmaiLHelper.getEmails(req.user._doc.profile_id , '/messages', req.user.accessToken)
      emailFetch = emailFetch.data
      res.send(emailFetch)
   } catch(error) {
      res.status(error.response.status)
      return res.send(error.message);
    })

})

需要调整此代码以匹配您从 axios 调用中收到的错误。

我还转换了代码以使用 try 和 catch 语法,因为您已经在使用异步了。


2
投票

在您的应用程序上使用express-async-errors

像这样

应用程序.ts

import 'express-async-errors'

稍后,配置您的应用程序以读取错误实例。

类自定义错误

class Error{
  
  public readonly message: string;
  public readonly statusCode: number;
  public readonly data?: any

  constructor(message: string, statusCode = 400, data?: any){
    this.message = message;
    this.statusCode = statusCode;
    this.data = data;
  }
}

export default Error

在您的应用程序上使用的中间件 -> app.use(youMiddleware())

import { Request, Response, NextFunction } from 'express'
import AppError from '../errors/AppError'

function globalErrors(err: Error, request: Request, response: Response, next: NextFunction) {

  if (err instanceof AppError) {
    response.status(err.statusCode).json({
      status: 'error',
      message: err.message,
      data: err?.data
    });
  }

  console.error(err);

  return response.status(500).json({
    status: 'error',
    message: 'Internal server error'
  });

}

export { globalErrors };

0
投票

(节点:31560)UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误的根源是在没有 catch 块的情况下抛出异步函数内部,或者拒绝未使用 .catch() 处理的 Promise。要在未处理的 Promise 拒绝时终止节点进程,请使用 CLI 标志

--unhandled-rejections=strict
(请参阅 https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。 (拒绝 ID:1) (节点:31560)[DEP0018] DeprecationWarning:未处理的承诺拒绝已被弃用。将来,未处理的 Promise 拒绝将会以非零退出代码终止 Node.js 进程。


-5
投票

我解决了这个问题。这很简单。如果您检查一下,问题可能是因为辅助变量有空格。为什么 ?我不知道,但你必须使用trim()方法才能解决问题

© www.soinside.com 2019 - 2024. All rights reserved.