如何让Express自定义错误处理器捕获所有错误?
解决Express自定义错误处理器无法捕获所有错误的问题
1. 正确挂载自定义错误处理器
你代码里已经引入了errorHandler但未实际使用,需将自定义错误处理器挂载到所有路由和普通中间件之后,这是Express错误中间件生效的必要条件:
require("dotenv").config(); const express = require("express"); const app = express(); const { logger } = require("./middleware/logger"); const { errorHandler } = require("./middleware/errorHandler"); const PORT = process.env.PORT || 3400; // 普通中间件 app.use(logger); // 在此处定义所有业务路由 // 自定义错误处理器必须放在最后 app.use(errorHandler); app.listen(PORT, () => { console.log(`Server is running on ${PORT}`); });
2. 捕获同步代码错误
- 路由/中间件内的同步错误:Express会自动传递给错误处理器,无需额外操作。
- 全局同步错误(如启动时的语法错误、未捕获的同步异常):需通过进程事件捕获:
// 在文件末尾添加 process.on('uncaughtException', (err) => { console.error('未捕获的同步异常:', err); // 可调用自定义错误处理逻辑,注意:此时应用状态不稳定,建议处理后退出进程 process.exit(1); });
3. 捕获异步代码错误
- 路由内的异步函数:必须用
try/catch包裹并调用next(err)传递错误,或直接返回Promise让Express自动捕获:
// 方式1:try/catch + next(err) app.get('/test', async (req, res, next) => { try { await someAsyncOperation(); } catch (err) { next(err); // 传递给自定义错误处理器 } }); // 方式2:直接返回Promise app.get('/test', async (req, res) => { // 若Promise拒绝,Express会自动捕获并传递给错误处理器 return await someAsyncOperation(); });
- 全局未处理的Promise拒绝:通过进程事件捕获:
process.on('unhandledRejection', (reason, promise) => { console.error('未处理的Promise拒绝:', reason); // 调用自定义错误处理逻辑后,建议退出进程 process.exit(1); });
4. 语法错误的特殊说明
语法错误属于启动阶段的致命错误,此时Express应用尚未完成初始化,根本无法进入自定义错误处理器。这类错误只能通过代码检查提前规避,或使用PM2等进程管理工具捕获并自动重启应用。如果是运行时动态生成代码导致的语法错误,同样需要通过uncaughtException事件捕获。
自定义错误处理器的标准写法
确保你的errorHandler符合Express错误中间件的规范(必须包含4个参数:err, req, res, next):
// ./middleware/errorHandler.js const errorHandler = (err, req, res, next) => { // 保留响应状态码,若无则设为500 const statusCode = res.statusCode !== 200 ? res.statusCode : 500; res.status(statusCode); res.json({ message: err.message, // 生产环境隐藏堆栈信息 stack: process.env.NODE_ENV === 'production' ? '🥞' : err.stack }); }; module.exports = { errorHandler };
内容的提问来源于stack exchange,提问作者plaze
相关产品推荐
相关产品推荐

