* 學習了怎么區分操作失敗,即那些可以被預測的哪怕在正確的程序里也無法避免的錯誤(例如,無法連接到服務器);而程序的Bug則是程序員失誤。
* 操作失敗可以被處理,也應當被處理。程序員的失誤無法被處理或可靠地恢復(本不應該這么做),嘗試這么做只會讓問題更難調試。
* 一個給定的函數,它處理異常的方式要么是同步(用throw方式)要么是異步的(用callback或者EventEmitter),不會兩者兼具。用戶可以在回調函數里處理錯誤,也可以使用?`try/catch`捕獲異常 ,但是不能一起用。實際上,使用throw并且期望調用者使用?`try/catch`?是很罕見的,因為 NodeJS 里的同步函數通常不會產生運行失敗(主要的例外是類似于`JSON.parse`的用戶輸入驗證函數)。
* 在寫新函數的時候,用文檔清楚地記錄函數預期的參數,包括它們的類型、是否有其它約束(例如必須是有效的IP地址),可能會發生的合理的操作失敗(例如無法解析主機名,連接服務器失敗,所有的服務器端錯誤),錯誤是怎么傳遞給調用者的(同步,用`throw`,還是異步,用 callback 和 EventEmitter)。
* 缺少參數或者參數無效是程序員的失誤,一旦發生總是應該拋出異常。函數的作者認為的可接受的參數可能會有一個灰色地帶,但是如果傳遞的是一個文檔里寫明接收的參數以外的東西,那就是一個程序員失誤。
* 傳遞錯誤的時候用標準的 Error 類和它標準的屬性。盡可能把額外的有用信息放在對應的屬性里。如果有可能,用約定的屬性名(如下)。