在路由异步中间件中抛出错误消息。

huangapple go评论81阅读模式
英文:

throwing error message in router async middleware

问题

这是我的路由器:

router.post('/post', isAccess, controller.create)

IsAccess 中间件

exports.isAccess = (request, result, next) => {
    const userid = '64c1248482bcfbb533b366d5';
    User.findOne({_id: userid}).select({role: 1}).then(user => {
        if (!role === 'routerRoleResource')) {
            const error = new Error('Authorization failed');
            error.status = 401;
            throw error;
        }
    }).catch(err => {
        if (!err.statusCode) err.statusCode = 500;
        next(err);
    });
    next();
}

尽管它在控制台中生成错误,但它没有停止路由中的处理,controller.create 仍然被调用。如果我移除 catch 并只有以下内容,我会得到以下错误:

exports.isAccess = (request, result, next) => {
    const userid = '64c1248482bcfbb533b366d5';
    User.findOne({_id: userid}).select({role: 1}).then(user => {
        if (!role === 'routerRoleResource')) {
            const error = new Error('Authorization failed');
            error.status = 401;
            throw error;
        }
    });
    next();
}

我尝试使用 async await 但是得到了相同的问题。然而,如果我有以下内容:

exports.isAccess = (request, result, next) => {
    const error = new Error('Authorization failed');
    error.status = 401;
    throw error;
    next();
}

它在 Postman 中完美工作:

然而,如果我只加上 async 关键字 (exports.isAccess = async (request, result, next)),它停止工作并生成错误。由于某种原因,错误模块在 async 或 promises 中不起作用。有人可以指导我正确的方向吗?

英文:

This is my router:

router.post('/post', isAccess, controller.create)

IsAccess middleware:

exports.isAccess=(request, result, next)=>{

    const userid='64c1248482bcfbb533b366d5'
    User.findOne({_id:userid}).select({role:1}).then(user=>{
        if(!role==='routerRoleResource'))
			{ const error=new Error('Authorization failed'); error.status=401; throw error }
    }).
    catch(err=>{
        if(!err.statusCode) err.statusCode=500;
        next(err)
    })
    next()
}

Although its generating an error in the console, it's not stopping the processing in the route and controller.create is still being called. It I remove the catch and have just this, I'm getting the following error:

exports.isAccess=(request, result, next)=>{

    const userid='64c1248482bcfbb533b366d5'
    User.findOne({_id:userid}).select({role:1}).then(user=>{
        if(!role==='routerRoleResource'))
			{ const error=new Error('Authorization failed'); error.status=401; throw error }
    })
    next()
}

在路由异步中间件中抛出错误消息。

I tried using async await but getting the same issue. However if I have the following:

exports.isAccess=(request, result, next)=>{    
    const error=new Error('Authorization failed'); 
    error.status=401; 
    throw error
    next()
}

It's working perfectly in postman:

在路由异步中间件中抛出错误消息。

However if I just put the async keyword ( exports.isAccess=async(request, result, next) ) it stops working and generate error. For some reason the error module is not working with async or promises. Anyone could point me in correct direction?

答案1

得分: 2

中间件没有阻止路由的处理并允许调用controller.create的原因是由于User.findOne()方法的异步性质。在isAccess中间件的第一个版本中,next()函数在.then()块之外被调用,这意味着它将在User.findOne()操作完成之前执行,因此在错误被抛出之前执行。

为了解决这个问题,你需要将next()函数移到.then()块内部,这样它只会在异步操作完成后才被调用。此外,你的if语句存在一个次要的语法问题。你应该将if (!role === 'routerRoleResource')更改为if (user.role !== 'routerRoleResource')。尝试使用修正后的中间件版本如下:

exports.isAccess = (request, response, next) => {
    const userid = '64c1248482bcfbb533b366d5'
    User.findOne({ _id: userid }).select({ role: 1 })
      .then(user => {
        if (user.role !== 'routerRoleResource') {
          const error = new Error('Authorization failed')
          error.status = 401
          throw error
        }
        // 继续执行下一个中间件或路由处理程序
        next()
      })
      .catch(err => {
        if (!err.statusCode) err.statusCode = 500;
        next(err)
      })
  }

请注意,此翻译仅包括你要求翻译的部分。

英文:

The reason the middleware is not stopping the processing in the route and allowing controller.create to be called is because of the asynchronous nature of the User.findOne() method. In the first version of the isAccess middleware, the next() function is called outside the .then() block, which means it will be executed before the User.findOne() operation is completed, and therefore, before the error is thrown.

To fix this issue, you need to move the next() function inside the .then() block, so it only gets called after the asynchronous operation is finished. Additionally, there is a minor syntax issue with your if statement. You should change if (!role === 'routerRoleResource') to if (user.role !== 'routerRoleResource'). Try this corrected version of the middleware,

exports.isAccess = (request, response, next) => {
    const userid = '64c1248482bcfbb533b366d5'
    User.findOne({ _id: userid }).select({ role: 1 })
      .then(user => {
        if (user.role !== 'routerRoleResource') {
          const error = new Error('Authorization failed')
          error.status = 401
          throw error
        }
        // Proceed to the next middleware or the route handler
        next()
      })
      .catch(err => {
        if (!err.statusCode) err.statusCode = 500;
        next(err)
      })
  }

huangapple
  • 本文由 发表于 2023年7月28日 01:59:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76782343.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定