Безопасно ли не разрешать или отклонять обещание?
Представьте себе веб-приложение с маршрутами, которое должно проверить, разрешен ли пользователю доступ к данному ресурсу, прежде чем продолжить. Проверка "аутентифицирована" основана на вызове базы данных.
На каждом маршруте я могу иметь:
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()
) становится более сложным, потому что он должен обрабатывать ошибки (либо с.catch()
или сnull
регистрироваться.then()
).
Две вещи заставляют меня немного нервничать:
Это нормально для обещания, возвращенногоauthorizeOwnership()
никогда не разрешаться в сценариях ошибок? Это приведет к задержке или утечке памяти?
Это логично, чтобы решитьconfirmOwnership()
с нулем сказать "не найден соответствующий ресурс", а затем рассматривать это как ошибку вauthorizeOwnership()
? Моя первая попытка отвергла обещание вconfirmOwnership()
когда не было соответствующего ресурса, но это усложняло ситуацию, потому что трудно различить это (случай 403) и фактическую ошибку (случай 500).