JavaScript 中的高级错误处理

錯誤處理是程式設計的一個基本方面,確保應用程式能夠優雅地處理意外情況。在 JavaScript 中,雖然 try-catch 是常用的,但還有更先進的技術來增強錯誤處理。

本文探討這些先進的方法,提供實用的解決方案來改善您的錯誤管理策略,使您的應用程式更加穩健。

什麼是錯誤處理?

錯誤處理的目的

錯誤處理預測、檢測並響應在程式執行過程中出現的問題。適當的錯誤處理改善了用戶體驗,維持應用程式的穩定性,並確保可靠性。

JavaScript 中的錯誤類型

  1. 語法錯誤。這些是程式碼語法中的錯誤,例如缺少括號或關鍵字的錯誤使用。
  2. 運行時錯誤。在執行過程中發生,例如訪問未定義對象的屬性。
  3. 邏輯錯誤。這些錯誤不會導致程式崩潰,但會導致不正確的結果,通常是由於邏輯錯誤或意外的副作用。

為什麼 try-catch 不夠用

try-catch 的限制

  • 範圍限制。僅處理其區塊內的同步代碼,並且不會影響異步操作,除非特別處理。
  • 靜默失敗。過度使用或不當使用可能導致錯誤被靜默忽略,潛在地造成意外行為。
  • 錯誤傳播。不原生支持在應用程序的不同層級之間傳播錯誤。

何時使用 try-catch

  • 同步代碼。對於處理 JSON 解析等同步操作中的錯誤非常有效。
  • 關鍵區域。用於保護關鍵代碼區域,因為錯誤可能會有嚴重後果。

自定義錯誤類:增強錯誤信息

創建自定義錯誤類

自定義錯誤類擴展內建的 Error 類,以提供額外的信息:

JavaScript

 

自定義錯誤的好處

  • 清晰度。提供特定的錯誤消息。
  • 細粒度處理。允許單獨處理特定錯誤類型。
  • 錯誤元數據。包含有關錯誤的額外上下文。

自定義錯誤的使用案例

  • 驗證失敗。與用戶輸入驗證相關的錯誤。
  • 領域特定錯誤。針對特定應用領域(如身份驗證或支付處理)量身定制的錯誤。

集中錯誤處理

Node.js 中的全局錯誤處理

使用中介軟件集中錯誤處理:

JavaScript

 

前端應用中的集中錯誤處理

在 React 中使用錯誤邊界實現集中式錯誤處理:

JavaScript

 

集中式錯誤處理的優點

  • 一致性。確保對錯誤管理採取統一的方法。
  • 更易於維護。集中式更新減少遺漏變更的風險。
  • 更好的日誌記錄和監控。促進與監控工具的整合。

錯誤傳播

同步代碼中的錯誤傳播

使用 throw 來傳播錯誤:

JavaScript

 

異步代碼中的錯誤傳播

使用 promises 或 async/await 處理錯誤:

JavaScript

 

何時傳播錯誤

  • 關鍵錯誤。傳播影響整個應用程序的錯誤。
  • 商業邏輯。允許高級組件處理商業邏輯錯誤。

異步代碼中的錯誤處理

使用 async/await 的錯誤處理

使用 try-catch 管理異步函數中的錯誤:

JavaScript

 

使用 Promise.all 進行錯誤處理

處理多個 promises 和錯誤:

JavaScript

 

異步錯誤處理中的常見陷阱

  • 未捕獲的 promises。始終使用 await.then().catch() 處理 promises。
  • 靜默失敗。確保錯誤不會被靜默吞噬。
  • 競爭條件。在處理並發的 非同步操作 時要小心。

錯誤日誌

客戶端錯誤日誌

捕獲全局錯誤:

JavaScript

 

伺服器端錯誤日誌

使用像 Winston 的工具進行伺服器端日誌記錄:

JavaScript

 

監控與警報

使用像 PagerDuty 或 Slack 的服務設置實時監控和警報:

JavaScript

 

錯誤日誌的最佳實踐

  1. 包含上下文。記錄請求數據和用戶信息等額外上下文。
  2. 避免過度日誌記錄。記錄必要的信息以防止性能問題。
  3. 定期分析日誌。定期檢查日誌以檢測並解決重複出現的問題。

優雅降級和備援

優雅降級

設計您的應用程序以在功能減少的情況下繼續運行:

JavaScript

 

備援機制

當主要操作失敗時提供替代方案:

JavaScript

 

實施優雅降級

  • UI 備援。當功能失效時提供替代的 UI 元素。
  • 數據備援。當即時數據不可用時使用緩存或默認值。
  • 重試機制。對於暫時性錯誤實施重試邏輯。

平衡優雅降級

平衡提供備援與讓用戶了解問題:

JavaScript

 

測試錯誤處理

單元測試錯誤處理

驗證單個函數中的錯誤處理:

JavaScript

 

整合測試

測試不同應用層之間的錯誤處理:

JavaScript

 

端到端測試

模擬現實場景以測試錯誤處理:

JavaScript

 

測試錯誤處理的最佳實踐

  1. 涵蓋邊緣案例。確保測試涵蓋各種錯誤場景。
  2. 測試備援。驗證備援機制按預期運作。
  3. 自動化測試。使用CI/CD 管道來自動化並確保穩健的錯誤處理。

現實場景

場景 1:支付處理系統

處理支付過程中的錯誤:

  • 自訂錯誤類別。使用類別如CardValidationErrorPaymentGatewayError
  • 重試邏輯。對網絡相關問題實施重試。
  • 集中日誌記錄。監控支付錯誤並及時解決問題。

場景 2:數據密集型應用

管理數據處理中的錯誤:

  • 優雅降級。提供部分數據或替代視圖。
  • 備用數據。使用快取或預設值。
  • 錯誤記錄。記錄詳細的上下文以進行故障排除。

場景 3:用戶身份驗證和授權

處理身份驗證和授權錯誤:

  • 自定義錯誤類別。創建類別,如 AuthenticationErrorAuthorizationError
  • 集中處理。記錄和監控與身份驗證相關的問題。
  • 優雅降級。提供替代登錄選項和有意義的錯誤消息。

結論

在 JavaScript 中進行高級錯誤處理需要超越簡單的 try-catch,擁抱自定義錯誤、集中處理、傳播和穩健測試。實施這些技術可以讓您構建出即使在出現問題時也能提供無縫用戶體驗的韌性應用程序。

進一步閱讀

  • 道格拉斯·克羅克福德 (Douglas Crockford) 的《JavaScript: The Good Parts》
  • 凱爾·辛普森 (Kyle Simpson) 的《You Don’t Know JS: Async & Performance》
  • MDN Web 文檔:錯誤處理

Source:
https://dzone.com/articles/advanced-error-handling-in-javascript-custom-error