英文:
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)
})
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论