错误处理根据异步风格而异,处理不当会导致静默失败或崩溃。关键规则:使用 try/catch 配合 async/await,始终处理 Promise 拒绝,永远不要让异步回调中的错误逃逸而不被处理。
async/await — 使用 try/catch
js
() {
{
user = db.(id);
user;
} (err) {
logger.(err);
(, { : err });
}
}
错误处理根据异步风格而异,处理不当会导致静默失败或崩溃。关键规则:使用 try/catch 配合 async/await,始终处理 Promise 拒绝,永远不要让异步回调中的错误逃逸而不被处理。
() {
{
user = db.(id);
user;
} (err) {
logger.(err);
(, { : err });
}
}
fetchData()
.then(process)
.catch(err => logger.error(err)); // an unhandled rejection can crash the process
没有 .catch 的 Promise 拒绝(或在 await 周围没有 try/catch)会变成未处理的拒绝 — 在现代 Node 中会终止进程。
// ❌ try/catch does NOT catch this — the throw happens on a LATER tick
try {
setTimeout(() => { throw new Error("boom"); }, 100);
} catch (e) { /* never runs */ }
try/catch 只捕获当前同步调用栈中的错误。当计时器/回调运行时,try 块已经消失。在回调内部处理错误。
// ❌ a rejected async handler isn't caught by Express → request hangs
app.get("/users", async (req, res) => {
const users = await db.getUsers(); // if this throws, Express doesn't catch it (pre-v5)
res.json(users);
});
// ✅ wrap to forward errors to Express's error handler
const asyncH = (fn) => (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
app.get("/users", asyncH(async (req, res) => {
res.json(await db.getUsers()); // errors now go to next() → error middleware
}));
process.on("unhandledRejection", (reason) => { logger.error(reason); });
process.on("uncaughtException", (err) => { logger.error(err); process.exit(1); });
这些是安全网用于日志记录,(对于未捕获的异常)干净地退出 — 不是处理错误的替代品。
未处理的异步错误是导致 Node 服务崩溃或静默损坏的主要原因。
掌握这些规则 — 在 await 周围使用 try/catch,始终 .catch Promises,在异步回调内部处理错误(try/catch 无法到达),并包装 Express 异步处理器以转发错误 — 防止请求挂起、静默失败和进程崩溃。
全局处理器提供了最后的安全网,但正确的逐个操作处理才是使异步 Node 代码健壮和可调试的基础。