想象一个带有路由的 Web 应用程序,在继续之前需要检查用户是否被允许访问给定的资源。“已验证”检查依赖于数据库调用。
在每条路线中,我可能有:
authorizeOwnership(req, res)
.then(function() {
// do stuff
res.send(200, "Yay");
});
我希望该authorizeOwnership()
函数能够处理 403(拒绝访问)和 500(例如数据库查询错误)响应,这样每个路由就不需要明确地这样做。
我有一个可以查询数据库以检查所有权的功能。
function confirmOwnership(resourceId, userId) {
// SequelizeJS... returns a bluebird promise
return Resource.find({
where: {id: resourceId, userId: userId}
})
.then(function(resource) {
if(!resource) {
return null; // no match for this resource id + user id
} else {
return resource;
}
});
}
然后将其用于authorizeOwnership
:
function authorizeOwnership(req, res) {
var rid = parseInt(req.params.rid, 10),
userId = parseInt(req.authInfo.userid, 10);
return new Promise(function(resolve, reject) {
confirmOwnership(rid, userId)
.then(function(resource) {
if(resource === null) {
res.send(403, "Forbidden");
// Note: we don't resolve; outer handler will not be called
} else {
resolve(resource);
}
})
.catch(function(err) {
console.log(err);
res.send(500, "Server error");
// Note: we don't resolve; outer handler will not be called
});
});
}
在这种情况下,我故意不调用reject()
或resolve()
在某些代码路径中。如果我这样做了,那么我的“外部”路由逻辑(正在调用的代码authorizeOwnership()
)会变得更加复杂,因为它必须处理错误(使用 a.catch()
或使用null
check in .then()
)。
不过有两件事让我有点紧张:
authorizeOwnership()
在错误场景中永远不会解决的承诺是否可以?它会导致延迟或内存泄漏吗?confirmOwnership()
用 null 解决说“找不到匹配的资源”然后将其视为错误在逻辑上是否合理authorizeOwnership()
?我的第一次尝试在没有匹配资源的情况下拒绝了承诺confirmOwnership()
,但这使事情变得更加复杂,因为很难区分这个(403 案例)和实际错误(500 案例)。