Express如何在异步代码中无需next()即可捕获抛出的Error?
无需手动调用next()捕获Express异步路由错误的实现方案
核心原理是通过高阶函数对所有路由处理逻辑做一层统一包装,自动捕获同步/异步抛出的错误并传递给全局错误处理链,无需开发者在每个路由里手动写try/catch调用next(err)。
具体实现步骤
- 第一步:编写异步路由处理包装器
/** * 路由处理函数包装器,自动捕获抛出的错误传递给错误中间件 * @param {Function} handler 原始路由处理函数 */ const wrapAsync = (handler) => (req, res, next) => { // 同步抛出的错误会被Promise.resolve隐式捕获,异步错误会被catch捕获 Promise.resolve(handler(req, res, next)).catch(next); };
- 第二步:注册路由时用包装器包裹业务逻辑
你提到的自定义NotAuthorized错误可以直接抛出,不需要手动调用next:
// 示例路由,直接抛出自定义错误即可 app.get('/api/user/info', wrapAsync(async (req, res) => { if (!req.session.userId) { throw new NotAuthorized('当前账号无访问权限'); } const userInfo = await UserModel.findById(req.session.userId); res.json({ code: 0, data: userInfo }); }));
- 第三步:编写全局错误处理中间件统一处理错误
// 注意:必须保留四个参数,Express才会将其识别为错误处理中间件 app.use((err, req, res, next) => { // 匹配自定义错误类型返回对应状态码 if (err instanceof NotAuthorized) { return res.status(401).json({ code: 401, message: err.message }); } // 其他错误兜底处理 res.status(500).json({ code: 500, message: '服务器内部错误' }); });
补充说明
该方案同时兼容同步路由和异步路由,不需要单独做适配。同步逻辑执行时抛出的错误会被Promise.resolve()包装为 rejected 状态的Promise,同样会被catch捕获并传递给全局错误链。
内容的提问来源于stack exchange,提问作者ryndm
相关产品推荐
相关产品推荐

