You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Express中处理已拒绝Promise,避免应用崩溃?

问题解决:Express中未处理的Promise拒绝导致应用崩溃

核心问题

你的transferColumnAmount函数没有返回Promise。函数内部调用db.tx()后链式调用了.then()和.catch(),但没有把整个Promise链返回出去。这导致await transferColumnAmount(...)实际等待的是undefined,原Promise的拒绝状态变成了未捕获的Promise拒绝,直接绕过了你的try/catch和错误中间件,最终导致应用崩溃。

修复步骤

1. 修复数据库函数,返回Promise

删掉多余的.then(result => result)和.catch(err => throw err)(这两个逻辑完全冗余),直接返回db.tx()创建的Promise链:

const transferColumnAmount = (fromTable, toTable, fromId, toId, column, amount) => {
  return db.tx(t => {
    return t.batch([
      t.one('UPDATE ${table:name} SET ${column:name} = ${column:name} + ${amount:csv} WHERE id = ${id:csv} RETURNING *', {
        table: fromTable,
        column: column,
        amount: -amount,
        id: fromId
      }),
      t.one('UPDATE ${table:name} SET ${column:name} = ${column:name} + ${amount:csv} WHERE id = ${id:csv} RETURNING *', {
        table: toTable,
        column: column,
        amount: amount,
        id: toId
      })
    ]);
  });
};

2. 优化错误处理(可选)

pg-promise的t.one()在未找到匹配记录时会抛出QueryResultError,可以在错误中间件里识别这类错误,返回更贴合业务的状态码和提示:

apiRouter.use((err, req, res, next) => {
  // 识别pg-promise的"未找到记录"错误
  if (err.name === 'QueryResultError' && err.code === 0) {
    err.status = 404;
    err.message = '指定的记录不存在';
  } else if (!err.status) {
    err.status = 500;
    err.message = err.message || '服务器内部错误';
  }
  res.status(err.status).send(err.message);
});

3. 确保异步操作被完整捕获

你的transferEnvelopeBudgetByIds中间件已经用try/catch包裹了await调用,修复数据库函数返回Promise后,拒绝的Promise会被try/catch捕获,再通过next(err)传递给错误中间件,不会再出现应用崩溃的情况。

额外建议

可以把数据库函数改成async/await风格,和中间件的代码风格保持一致,可读性更强:

const transferColumnAmount = async (fromTable, toTable, fromId, toId, column, amount) => {
  return db.tx(async t => {
    const [fromResult, toResult] = await t.batch([
      t.one('UPDATE ${table:name} SET ${column:name} = ${column:name} + ${amount:csv} WHERE id = ${id:csv} RETURNING *', {
        table: fromTable,
        column: column,
        amount: -amount,
        id: fromId
      }),
      t.one('UPDATE ${table:name} SET ${column:name} = ${column:name} + ${amount:csv} WHERE id = ${id:csv} RETURNING *', {
        table: toTable,
        column: column,
        amount: amount,
        id: toId
      })
    ]);
    return [fromResult, toResult];
  });
};

内容的提问来源于stack exchange,提问作者Brenden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:55:08