簡體   English   中英

在Node.js中暴露和組合錯誤的最佳方法是什么?

[英]What's the best way to expose and compose errors in Node.js?

我正在編寫一個與REST API對話的模塊,並且由於REST API提供了良好的語義錯誤響應(例如403與503),我想將這些語義錯誤傳達給調用者。

(編輯:我的意思是,調用者應該能夠以編程方式理解錯誤的原因並采取相應的行動,例如顯示相應的UI。)

對我來說最好的方法是什么?

  1. 為那些語義創建我自己的Error子類,例如mymodule.ForbiddenErrormymodule.ServiceUnavailableError 然后,調用者將檢查instanceof以獲取語義。 這在靜態類型語言(如C#和Java)中最為常見。

  2. mymoduleCode屬性添加到標准的Error實例中,使用'Forbidden''ServiceUnavailable'等語義字符串。 Node.js本身就是這樣做的,例如code: 'ECONNREFUSED'

  3. 還有其他方法嗎?

==

我現在正在編寫另一個模塊,它包裝了第一個模塊。 我不想直接公開內部模塊的錯誤,但為了可調試性,編寫/包裝它們會很好。

對我來說,最好的方法是什么呢?

  1. 添加如一個internalError屬性為我的Error實例引用內部模塊的Error實例。 C#和Java再次這樣做。 Exception#InnerException / Throwable#cause

  2. 還有其他方法嗎?

但是,我見過的大多數工具只顯示Error實例的stack屬性,因此在這些情況下這些數據會丟失。 是否存在已經存在的典型/傳統方式?

您描述的用例是Node現在無法滿足的用例。 由於使用的慣例,它們往往是以下的混合物:

  1. 創建簡單派生自Error構造函數的新錯誤類型。 主要用於創建高級錯誤類別。 可以使用instanceof來區分錯誤類型,但感覺不是非常JavaScripty。
  2. 創建Java樣式的Error子類型,將另一個錯誤作為構造函數參數,然后將其包裝起來。 如果您使子類型公開API,那么您基本上使用多態而不是直接分派來根據類型處理錯誤。
  3. 通過Error構造函數創建語義上有用的錯誤消息。 這是我傾向於使用很多的模式。
  4. 將屬性附加到錯誤,這也是非常常見的。
  5. 創建一個解耦的錯誤處理API,可以從錯誤發生的任何地方調用它。 這為您提供了一個集中所有代碼的地方,這些代碼可以確定您遇到的錯誤類型以及應該如何處理錯誤,並注入處理錯誤所需的任何依賴項。

這里真正的問題是這些都是臨時機制,我不會說它們中的任何一個已達到臨界質量。 我認為這部分是由於異步性和JavaScript的結合使得很難正確並完全處理錯誤,因此建議通常在捕獲有關錯誤的信息后關閉整個過程。

這並不能很好地處理預期的錯誤,但我認為大多數錯誤都是由框架捕獲的(例如Express錯誤處理程序)或者放入Node回調約定。 簡而言之,我認為這里有空間來定義一些慣例,因為最先進的技術並不是那么巧妙。

發現這篇很棒的文章談到這個:

http://www.joyent.com/developers/node/design/errors

這里粘貼太多,但在“具體建議”下,第2至5項解決了這個問題:

  1. 清楚你的功能是做什么的。
  2. 對所有錯誤使用Error對象(或子類),並實現Error契約。
  3. 使用Error的name屬性以編程方式區分錯誤。
  4. 使用解釋詳細信息的屬性擴充Error對象
  5. 如果將較低級別的錯誤傳遞給調用者,請考慮將其包裝。

特別是,該文章鏈接到此模塊以包裝/撰寫錯誤:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM