3 回答

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超10個(gè)贊
此行為完全類似于同步拋出:
try{
throw new Error();
} catch(e){
// handle
}
// this code will run, since you recovered from the error!
那是.catch要從錯(cuò)誤中恢復(fù)的一半??赡苄枰匦聮伋鲂盘?hào)以指示狀態(tài)仍然是錯(cuò)誤:
try{
throw new Error();
} catch(e){
// handle
throw e; // or a wrapper over e so we know it wasn't handled
}
// this code will not run
但是,僅此一種方法對(duì)您而言不起作用,因?yàn)樵撳e(cuò)誤將由以后的處理程序捕獲。真正的問(wèn)題是,廣義的“ HANDLE ANYTHING”錯(cuò)誤處理程序通常是一種不好的做法,在其他編程語(yǔ)言和生態(tài)系統(tǒng)中卻極少使用。因此,藍(lán)鳥(niǎo)提供了類型化和謂詞性的捕獲。
附加的優(yōu)點(diǎn)是您的業(yè)務(wù)邏輯根本不需要(也不應(yīng)該)知道請(qǐng)求/響應(yīng)周期。決定客戶端獲取哪種HTTP狀態(tài)和錯(cuò)誤不是查詢的責(zé)任,而隨著應(yīng)用的增長(zhǎng),您可能希望將業(yè)務(wù)邏輯(如何查詢數(shù)據(jù)庫(kù)以及如何處理數(shù)據(jù))與發(fā)送給客戶端的內(nèi)容分開(kāi)(什么http狀態(tài)代碼,什么文本和什么響應(yīng))。
這是我編寫(xiě)您的代碼的方式。
首先,我將.Query拋出一個(gè)NoSuchAccountError,將其從Promise.OperationalErrorBluebird已經(jīng)提供的子類化。如果您不確定如何將錯(cuò)誤歸類,請(qǐng)告訴我。
我另外為其子類化AuthenticationError,然后執(zhí)行類似的操作:
function changePassword(queryDataEtc){
return repository.Query(getAccountByIdQuery)
.then(convertDocumentToModel)
.then(verifyOldPassword)
.then(changePassword);
}
如您所見(jiàn)-它非常干凈,您可以閱讀文本,就像使用說(shuō)明書(shū)一樣,了解過(guò)程中發(fā)生的情況。它也與請(qǐng)求/響應(yīng)分開(kāi)。
現(xiàn)在,我將從路由處理程序中這樣調(diào)用它:
changePassword(params)
.catch(NoSuchAccountError, function(e){
res.status(404).send({ error: "No account found with this Id" });
}).catch(AuthenticationError, function(e){
res.status(406).send({ OldPassword: error });
}).error(function(e){ // catches any remaining operational errors
res.status(500).send({ error: "Unable to change password" });
}).catch(function(e){
res.status(500).send({ error: "Unknown internal server error" });
});
這樣,邏輯就全部集中在一個(gè)地方,而如何為客戶處理錯(cuò)誤的決定就都集中在一個(gè)地方,而且它們不會(huì)相互干擾。

TA貢獻(xiàn)1936條經(jīng)驗(yàn) 獲得超7個(gè)贊
.catch就像try-catch語(yǔ)句一樣工作,這意味著最后只需要一個(gè)捕獲即可:
repository.Query(getAccountByIdQuery)
.then(convertDocumentToModel)
.then(verifyOldPassword)
.then(changePassword)
.then(function(){
res.status(200).send();
})
.catch(function(error) {
if (/*see if error is not found error*/) {
res.status(404).send({ error: "No account found with this Id" });
} else if (/*see if error is verification error*/) {
res.status(406).send({ OldPassword: error });
} else {
console.log(error);
res.status(500).send({ error: "Unable to change password" });
}
});

TA貢獻(xiàn)1874條經(jīng)驗(yàn) 獲得超12個(gè)贊
我想知道是否存在一種方法可以根據(jù)錯(cuò)誤以某種方式強(qiáng)制鏈條停止在某個(gè)點(diǎn)
不可以。除非您拋出一個(gè)冒泡直到結(jié)束的異常,否則您無(wú)法真正“終止”一條鏈。
他的模式的派生將不是區(qū)分錯(cuò)誤類型,而是使用具有statusCode和body字段的錯(cuò)誤,這些錯(cuò)誤和字段可以從單個(gè)通用.catch處理程序發(fā)送。根據(jù)您的應(yīng)用程序結(jié)構(gòu),他的解決方案可能會(huì)更干凈。
或者是否有更好的方法來(lái)構(gòu)造它以獲得某種形式的分支行為
是的,您可以使用promises進(jìn)行分支。但是,這意味著離開(kāi)鏈并“返回”嵌套-就像您在嵌套的if-else或try-catch語(yǔ)句中所做的那樣:
repository.Query(getAccountByIdQuery)
.then(function(account) {
? ? return convertDocumentToModel(account)
? ? .then(verifyOldPassword)
? ? .then(function(verification) {
? ? ? ? return changePassword(verification)
? ? ? ? .then(function() {
? ? ? ? ? ? res.status(200).send();
? ? ? ? })
? ? }, function(verificationError) {
? ? ? ? res.status(406).send({ OldPassword: error });
? ? })
}, function(accountError){
? ? res.status(404).send({ error: "No account found with this Id" });
})
.catch(function(error){
? ? console.log(error);
? ? res.status(500).send({ error: "Unable to change password" });
});
添加回答
舉報(bào)