我在节点应用中使用kriskowal Q promise库。 我有代码读取文件,然后尝试将其中的一部分解析为Javascript Date对象(我在尝试执行JSON.parse的其他地方有类似的代码)。在这些情况下,我已阅读并个人认为最佳做法是将该代码包装在try / catch块中以避免并可能导致致命的意外。这里有一些与伪代码混合的真实代码:
var getMonitorTimestamp = function() {
return readLogFile()
.then(
function ok(contents) {
//regex to capture dates in format of: 09 Jan 2015 09:42:01
var regex = /[0-9]{2} [\w]{3} [0-9]{4} ([0-9]{2}:){2}[0-9]{2}/g;
var timestamp = contents.match(regex)[0];
var date;
try {
date = new Date(timestamp);
return date;
}
//when I've caught the error here, how do I reject the promise?
//this will still return an error to the next success callback in the queue
catch(e) {
console.error(e);
return e;
}
},
function err(e) {
console.error(e);
return new Error();
}
);
};
exports.sendRes = function(req, res) {
getMonitorTimestamp()
.then(
function yay(data) {
//don't want to send an error here
res.json({result: data});
},
function boo(e) {
res.status(500).json({error: e});
}
);
}
正如您所看到的,拒绝getMonitorTimstamp-> ok回调中的promise是有用的,因为它失败了。
Q中有没有办法做到这一点?我还没找到任何东西。或者处理这种情况有不同的模式吗?
答案 0 :(得分:4)
这实际上已在Handling Errors部分的q文档中介绍。
您不想使用.then(success, fail)
样式,而是希望链接处理程序以允许成功处理程序throw
到失败处理程序。
readLogFile()
.then(function yay(data) {
throw "Eek!";
})
.fail(function boo(e) {
res.status(500).json({error: e});
});
答案 1 :(得分:0)
实际上,如果您使用此构造(如Q documentation中所述),则不需要在then
函数中捕获异常:
function a () {
return methodThatReturnsAPromise().then(function () {
// Exceptions can happen here
})
}
a()
.then(function () { /* Success */ })
.catch(function (err) { /* Error */ })
异常将传播到承诺的接收者。
至于你的代码:
您可以获得例外情况,但如果您发现错误情况(不是由例外引起),您可以在readLogFile().then(...
函数中返回新拒绝的承诺:
var getMonitorTimestamp = function() {
return readLogFile()
.then(function (contents) {
if (<check errors here>) {
// Found the error condition
return Q.reject(‘Failed here’)
} else {
// Return the normal result
...
return date
}
})
}
在代码的最顶层留下一个catch
子句:
exports.sendRes = function(req, res) {
getMonitorTimestamp()
.then(function (data) {
res.json({result: data})
})
.catch(function (e) {
res.status(500).json({error: e})
})
}