【问题标题】:Handling Unhandled promise rejection in express application处理快递申请中未处理的承诺拒绝
【发布时间】:2021-12-11 21:05:52
【问题描述】:

我有一个现有的 Node Express 应用程序并希望更好地改进错误处理。我当前的路由端点定义如下,

app.get('/example/getActiveId', async (req, res, next) => {
  // Some code to fetch some details from request and do some validations

  try {
    const result = await api.getActiveId(id); 
    res.json({ success: true, result });       // I am getting this response in all the time.
  } catch (err) {
    console.log('getActiveId', err)
    console.error(err);
    res.json({ success: false });
  }
});

另外,我在所有路由路径的最后定义了错误中间件。

// error handler middleware
app.use((error, req, res, next) => {
  console.log('in Error middleware')
  console.error(error.stack);
  res.status(500).send(error.message || 'Something Broke!');
 })

我对@9​​87654323@的定义如下。

 exports.getActiveId = id => axiosInstance
  .get('/example')
  .then(({ data }) => data)
  .catch(er => er);

上面getActiveId定义的问题是每次getActiveId的catch,执行落入上面端点定义的try块。我希望执行应该进入 catch 块端点定义函数。这样我就可以调用next(err) 调用默认的快速错误处理中间件。

所以我尝试了以下样机代码来模拟相同的承诺拒绝。

exports.getActiveId = id => {
    const __mockPromise = () => {
        return new Promise((resolve, reject) => {
            reject('Problem in getActiveId')
        })
    }

    return new Promise((resolve, reject) => {
        __mockPromise().then(({ data }) => resolve(data)).catch(er => { console.log('in catch....'); reject(er) })
    });
}

我希望上面的函数会进入终点函数定义的catch块。

但这次我收到以下错误,

in catch....
(node:32897) UnhandledPromiseRejectionWarning: Problem in getActiveId
(node:32897) 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(). (rejection id: 4)

如何修复此错误并绕过执行到错误中间件?

【问题讨论】:

    标签: node.js express exception unhandled-exception unhandled-promise-rejection


    【解决方案1】:

    使用您当前的代码,api.getActiveId 总是返回一个 resolved 承诺

    • 如果axiosInstance.get 成功,则解析为data
    • 如果axiosInstance.get 失败,.catch(er => er) 会使其解析为er

    如果您希望 api.getActiveId 返回一个被 rejecteder 的承诺,请省略 .catch(er => er)

    例如,如果您使用以下输入运行 Node.js

    const getActiveId = () => Promise.reject("error")
      .then(({ data }) => data);
    async function test() {
      try {
        const result = await getActiveId();
        console.log(result);
      } catch (err) {
        console.error(err);
      }
    }
    test();
    

    将到达console.error 语句,并且不会报告未处理的承诺拒绝。

    【讨论】:

    • 我们可以对 Mock 函数做同样的事情吗?如果我按照上述步骤操作,我会得到 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(). (rejection id: 2)
    • 我不明白你的模拟函数的目的。如果api.getActiveId 返回一个被拒绝的承诺,你的异步中间件中的catch 将处理它。
    • 我无法发送使轴实例出错的情况。所以我做了一个模型函数,它能够发布拒绝呼叫并测试我的代码。但它没有按应有的方式工作。
    • 确实,当我尝试同样的方法时,拒绝由我的catch 块处理。
    • 但是我得到了所有的响应来尝试 API 端点定义块。意味着,我得到了{success: true}。但是对于 Axios 调用(或)模型调用的失败响应,我需要得到 {success: false}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 2023-03-17
    • 2018-04-01
    • 2021-09-19
    相关资源
    最近更新 更多