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

Router异步中间件抛出异常失效问题求助

问题原因分析
  • 异步代码执行顺序错误:原代码里的next()写在Promise链外面,会立刻执行,不管数据库查询的异步操作有没有完成、有没有报错。这就导致哪怕权限校验失败,controller.create已经被调用了,后面的next(err)只是走错误处理流程,但正常路由流程已经跑完了。
  • 同步场景下,throw error会直接中断函数,后面的next()根本不会执行,所以能正确终止路由,把错误交给Express的错误处理中间件。
  • 加async关键字后,async函数内部的错误会被包装成Promise的reject,但如果没正确捕获或者还是提前调用了next,Express没法自动处理这个reject,就会导致错误处理失效。
解决方案

方案1:修复Promise链式调用写法

把next()移到Promise链里,只有权限校验通过才调用,错误时在catch里传错误给next:

exports.isAccess = (request, result, next) => {
    const userid = '64c1248482bcfbb533b366d5';
    User.findOne({ _id: userid }).select({ role: 1 })
        .then(user => {
            // 原代码里role未定义,这里要改成user.role,同时修正判断逻辑
            if (user.role !== 'routerRoleResource') {
                const error = new Error('Authorization failed');
                error.statusCode = 401;
                throw error;
            }
            // 校验通过才进入下一个中间件
            next();
        })
        .catch(err => {
            if (!err.statusCode) err.statusCode = 500;
            next(err);
        });
    // 删掉这里的next(),避免提前触发后续路由
};

方案2:用async/await写法

用try/catch捕获异步错误,同样只在校验通过时调用next():

exports.isAccess = async (request, result, next) => {
    try {
        const userid = '64c1248482bcfbb533b366d5';
        const user = await User.findOne({ _id: userid }).select({ role: 1 });
        if (user.role !== 'routerRoleResource') {
            const error = new Error('Authorization failed');
            error.statusCode = 401;
            throw error;
        }
        // 权限没问题,继续走路由
        next();
    } catch (err) {
        if (!err.statusCode) err.statusCode = 500;
        next(err);
    }
};
额外提醒
  • 原代码里的if(!role==='routerRoleResource')有两个bug:一是role没定义(应该取user.role),二是逻辑判断优先级错了,正确写法是user.role !== 'routerRoleResource'。
  • Express里,async中间件的错误最好用try/catch捕获后通过next(err)传递,部分新版本Express能自动捕获async函数的reject,但显式处理更稳妥。

内容的提问来源于stack exchange,提问作者D. Rattansingh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 21:13:14