0

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()
}

enter image description here

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:

enter image description here

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?

D. Rattansingh
  • 1,569
  • 3
  • 19
  • 30

1 Answers1

2

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)
      })
  }
Nazrul Chowdhury
  • 1,483
  • 1
  • 5
  • 11