查询接口的 await 抛了 ER_NO_SUCH_TABLE,进程直接退出,pm2 日志里只有一行 unhandledRejection。同样的逻辑写在同步路由里,客户端能收到 500。碰到这种情况,我一般先确认改动有没有真的生效。

原因不复杂,Express 4 只认同步 throw 和 next(err),async 函数返回的 Promise 被 reject 之后没人接,最后落到 process 的 unhandledRejection。默认没有监听器时 Node 会以非零码退出。

「Express 异步错误」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。报错里带路径的,先去看那个路径在不在、权限对不对。

const wrap = fn => (req, res, next) =>
  Promise.resolve(fn(req, res, next)).catch(next);
app.get('/orders', wrap(async (req, res) => {
  res.json(await db.query('SELECT 1'));
}));

同一份配置存在多处的,先确认改的是被加载的那一份。新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。

备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。

具体做法是,每个 async 路由外包一层 try/catch 把错误交给 next;或者装 express-async-errors 在启动时统一接管;升级到 Express 5 之后 async 抛错会自动进错误中间件;确认错误中间件是四个参数 少一个签名不会生效。

最后用这个标准收尾,把表名改错再请求一次 客户端拿到 500 进程 PID 没有变化。

作者 9823189