[英]What's the best way to expose and compose errors in Node.js?
我正在編寫一個與REST API對話的模塊,並且由於REST API提供了良好的語義錯誤響應(例如403與503),我想將這些語義錯誤傳達給調用者。
(編輯:我的意思是,調用者應該能夠以編程方式理解錯誤的原因並采取相應的行動,例如顯示相應的UI。)
對我來說最好的方法是什么?
為那些語義創建我自己的Error
子類,例如mymodule.ForbiddenError
, mymodule.ServiceUnavailableError
? 然后,調用者將檢查instanceof
以獲取語義。 這在靜態類型語言(如C#和Java)中最為常見。
將mymoduleCode
屬性添加到標准的Error
實例中,使用'Forbidden'
或'ServiceUnavailable'
等語義字符串。 Node.js本身就是這樣做的,例如code: 'ECONNREFUSED'
。
還有其他方法嗎?
==
我現在正在編寫另一個模塊,它包裝了第一個模塊。 我不想直接公開內部模塊的錯誤,但為了可調試性,編寫/包裝它們會很好。
對我來說,最好的方法是什么呢?
添加如一個internalError
屬性為我的Error
實例引用內部模塊的Error
實例。 C#和Java再次這樣做。 ( Exception#InnerException / Throwable#cause )
還有其他方法嗎?
但是,我見過的大多數工具只顯示Error
實例的stack
屬性,因此在這些情況下這些數據會丟失。 是否存在已經存在的典型/傳統方式?
您描述的用例是Node現在無法滿足的用例。 由於使用的慣例,它們往往是以下的混合物:
instanceof
來區分錯誤類型,但感覺不是非常JavaScripty。 這里真正的問題是這些都是臨時機制,我不會說它們中的任何一個已達到臨界質量。 我認為這部分是由於異步性和JavaScript的結合使得很難正確並完全處理錯誤,因此建議通常在捕獲有關錯誤的信息后關閉整個過程。
這並不能很好地處理預期的錯誤,但我認為大多數錯誤都是由框架捕獲的(例如Express錯誤處理程序)或者放入Node回調約定。 簡而言之,我認為這里有空間來定義一些慣例,因為最先進的技術並不是那么巧妙。
發現這篇很棒的文章談到這個:
http://www.joyent.com/developers/node/design/errors
這里粘貼太多,但在“具體建議”下,第2至5項解決了這個問題:
- 清楚你的功能是做什么的。
- 對所有錯誤使用
Error
對象(或子類),並實現Error
契約。- 使用Error的
name
屬性以編程方式區分錯誤。- 使用解釋詳細信息的屬性擴充
Error
對象- 如果將較低級別的錯誤傳遞給調用者,請考慮將其包裝。
特別是,該文章鏈接到此模塊以包裝/撰寫錯誤:
https://github.com/joyent/node-verror
我不確定我是否必須遵循這些確切的約定 - 例如,我看到了具有應用程序域code
屬性的價值 - 但原則非常有用。
編輯我是StackOverflow 和 Node.js的新手。 別人應該回答這個問題! :-)
如果您來自Java / C#歡迎使用JavaScript! 我從未見過Node.js庫使用instanceof
來檢查錯誤類型,但正如你所說的那樣在靜態語言中很常見。
話雖如此,通常只會創建新的錯誤,並回調那些使用NodeJS的回調樣式(err, response)
。
我一直遇到來自其他模塊的錯誤消息,知道它們來自何處以及創建包含的錯誤消息是有幫助的,這些錯誤消息可能隱藏它實際上在我身上死亡的地方(我需要更多的東西來挖掘)。
創建一個可以處理字符串的休息錯誤消息的函數的示例(或者在您的情況下,響應無效):
function myFunction(callback) {
callRestAPI('http://someApi.com/request', function(errorString, jsonResponse) {
if (errorString) {
callback(new Error("something wrong in myFunction! " + errorString));
} else {
callback(null, JSON.parse(jsonResponse));
}
});
}
在您的情況下,“errorString”檢查基本上是響應(403/503),您可以構造您的錯誤消息以發送到new Error( ... )
,例如new Error('Failed! Got response 403!')
我可能錯過了你的觀點,也許別人可以更徹底。
重新閱讀后,你可以發布你正在包裝的模塊。 是節點請求嗎?
我對節點也很陌生,所以請稍等一下,但我會選擇你的#2選項,添加一個屬性。 (這也是在這里提出的) 。
這幾乎是你最初的#2選項。 如果錯誤處理程序只記錄堆棧,而不是錯誤本身,那就是他們的錯誤。 :-)(嚴肅的,不知道你怎么能做得更好)
我只是將一個httpCode
屬性附加到錯誤對象。 吻
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.