处理快递申请中未处理的承诺拒绝

Posted

技术标签:

【中文标题】处理快递申请中未处理的承诺拒绝【英文标题】: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)

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

【问题讨论】:

【参考方案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

以上是关于处理快递申请中未处理的承诺拒绝的主要内容,如果未能解决你的问题,请参考以下文章

Puppeteer -Getting UnhandledPromiseRejectionWarning:管道中未处理的承诺拒绝

MDM证书申请的流程

Auth0 处理拒绝的权限

MDM 证书申请流程(vendor及customer)

处理多个承诺拒绝[重复]

申请快递100