【发布时间】:2019-07-20 09:24:54
【问题描述】:
我正在一个新的代码库中工作,该代码库的模式是一些可重用函数从链中返回一个承诺,但它们不处理错误。
这是一个例子:
function createScheduleForGroup(group) {
if (notInProduction()) {
group.gschedScheduleId = '0';
return Bluebird.resolve(group);
}
// note: schedule is a global within the file
return schedule.createSchedule(group.name).then(function (schedule) {
group.gschedScheduleId = schedule.id;
return group.save();
});
}
在上面的示例中,没有 .catch 或 reject 函数传递给 .then。
该函数最终用于处理错误的快速路由中:
router.post('/schedule', function(req, res, next) {
scheduleLogical
.createScheduleGroup(req[config.entity])
.then(function(group) {
res.status(201).json(group);
})
.catch(next);
// if creteScheduleGroup throws an error it is handled here
不为函数返回的 Promise 定义错误处理程序并预测使用该函数的人附加适当的错误处理程序是否是一种常见模式?
为了让我自己的理解更清楚,我对这个特定的函数和 Promise 链中使用的所有函数进行了模拟。这里是:
function getScheduleMock() {
// this promise promisifys an older api that uses callbacks
return new Promise((resolve, reject) => {
// note this is simulating an api call:
const response = Math.round(Math.random());
// 0 === err, 1 === success
if(response === 0) return reject(response);
resolve(response);
})
// error hanlding :)
.catch(err => {
console.log(err);
return Promise.reject(err);
// there is an error handling function that logs the errors. If the error doesn't match expected errors, it rejects the error again as I have here.
})
.then(responseData => {
return Promise.resolve(responseData);
})
}
function createScheduleForGroupMock() {
return getScheduleMock().then(responseData => Promise.resolve('everything worked :)'));
// Note: group.save() from the original returns a promise
// just like the actual example, the promise is returned
// but there isn't any form of error handling except within the getScheduleMock function
}
createScheduleForGroupMock(); // when the error is rejected in the .catch() in getScheduleMock, the error is unhandled.
/* ***************** */
/* the createScheduleForGroup method is used within an express route which has error handling, here is an example of the code: */
// router.post('/schedule', function(req, res, next) {
// scheduleLogical
// .createScheduleGroup(req[config.entity])
// .then(function(group) {
// res.status(201).json(group);
// })
// .catch(next);
// if creteScheduleGroup throws an error it is handled here
我对错误处理承诺相当陌生,从我一直在阅读和练习的内容来看,我通常认为您应该始终包含错误处理程序。我正在使用的代码库有很多使用createScheduleForGroup 模式的方法,其中没有在函数中定义错误处理程序,而是在使用函数后对其进行处理和附加。
createScheduleForGroup 中使用的一些函数会处理它们自己的错误,我对何时处理返回承诺的函数中的错误以及何时在使用该函数时附加它们的平衡感到困惑和好奇。
【问题讨论】:
-
Promise 错误处理与传统的错误处理没有什么不同,只有在可以优雅处理错误时才应该
catch,在所有其他情况下,错误处理应该推迟到调用方法。 -
我还要补充一点,catch-log-rethrow 是一种反模式。理想情况下,您应该将错误气泡一直到处理程序,该处理程序在关闭和重新启动应用程序之前记录错误,或者在处理错误时记录错误(如果需要)。
标签: javascript