> ## Documentation Index
> Fetch the complete documentation index at: https://meta.niceshare.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 快速失敗原則

> 快速失敗原則倡導在開發早期偵測並報告錯誤。了解其起源、優勢以及如何有效應用。

<Info>
  **類別**：原則<br />
  **類型**：軟體開發原則<br />
  **來源**：軟體工程，1970年代 / 《程式設計師》，1999<br />
  **別名**：快速失敗、早失敗偵測
</Info>

<Note>
  **快速回答** —
  快速失敗原則指出，系統應在偵測到錯誤時立即報告，而不是嘗試用無效狀態繼續執行。該原則在安迪·亨特（Andy
  Hunt）和戴夫·湯瑪斯（Dave Thomas）1999
  年出版的《程式設計師》中推廣，已成為構建健壯軟體的基礎理念。其核心思想是：立即失敗使除錯更容易，防止級聯失敗，並降低修復缺陷的成本。
</Note>

## 什麼是快速失敗原則？

快速失敗原則是一種軟體開發哲學，主張在出現問題時立即失敗，而不是嘗試用損壞或無效的狀態繼續執行。其背後的原理是務實的：透過快速、明確地失敗，開發人員可以在最早的時機識別並修復問題，此時上下文最清晰，修正成本也最低。

> 「當你遇到問題時，停止嘗試做你原本在做的事情。系統已經失敗——立即處理失敗。」—— 安迪·亨特和戴夫·湯瑪斯，《程式設計師》

該原則適用於軟體開發的多個層面。在程式碼層面，它表現為嚴格的輸入驗證，在偵測到無效資料時立即拋出例外。在架構層面，它表現為系統在依賴項失敗時優雅地停止，而不是嘗試以不可預測的行為進行降級操作。在組織層面，它影響團隊如何優先考慮快速回饋週期，而不是在沒有驗證的情況下進行擴展開發。

### 快速失敗原則的三層理解

* **入門**：編寫程式碼時，在函數入口點驗證輸入。如果資料無效，立即拋出清晰的錯誤訊息，而不是嘗試繼續執行，在後面造成更混亂的失敗。
* **實務**：在系統邊界設計明確的檢查。當外部服務或 API 失敗時，快速失敗而不是透過變通方法或靜默失敗來累積技術負債。
* **進階**：在快速失敗和彈性模式之間取得平衡。在分散式系統中，區分暫時性失敗（重試可能會成功）和永久性失敗（快速失敗是正確的）。應用斷路器來防止級聯失敗，同時在系統邊界維護快速失敗的語義。

## 起源

快速失敗原則源於電腦科學研究，可回溯到 1970 年代，尤其是在例外處理和健壯系統設計方面的工作。然而，它透過安迪·亨特和戴夫·湯瑪斯 1999 年出版的《程式設計師：從小工到專家》獲得了廣泛認可，該書將其闡述為務實軟體開發的核心理原則。

該原則源於這樣的認識：嘗試在偵測到錯誤後繼續執行往往會導致比立即失敗更糟糕的結果。當軟體嘗試在沒有足夠上下文的情況下「恢復」錯誤時，它經常會在下游產生更難診斷的問題。補救措施是快速失敗——立即停止，保留錯誤上下文，讓開發人員解決根本原因。

亨特和湯瑪斯將快速失敗定位為更廣泛「儘早偵測錯誤」哲學的一部分。他們認為，缺陷的修復成本隨著在開發週期中發現時間的推後呈指數增長。透過立即失敗，開發人員可以保留寶貴的除錯上下文：堆疊追蹤、變數值和程式狀態，否則這些會因繼續執行而丟失或損壞。

## 核心要點

<Steps>
  <Step title="保留除錯上下文">
    當失敗立即發生時，開發人員可以準確看到什麼問題、提供了什麼輸入，以及失敗時刻的系統狀態是什麼。
  </Step>

  <Step title="防止級聯失敗">
    透過在出現問題的第一個跡象時停止執行，快速失敗可以防止小錯誤演變為更大、更難診斷和恢復的系統故障。
  </Step>

  <Step title="降低缺陷成本">
    在開發早期發現和修復缺陷远比在生產中發現它們便宜得多。快速失敗加速了這一發現過程。
  </Step>

  <Step title="提高系統可靠性">
    快速失敗的系統更加可預測。使用者和運維人員理解失敗將是可見的、可操作的，而不是靜默地損壞資料。
  </Step>
</Steps>

## 應用場景

<CardGroup cols={2}>
  <Card title="輸入驗證">
    在函數邊界驗證所有輸入。
    如果必需參數缺失、為空或超出預期範圍，立即拋出例外。
  </Card>

  <Card title="設定檢查">
    在啟動時驗證設定檔和環境變數。如果必需設定缺失或無效，立即失敗，而不是以不一致的狀態啟動。
  </Card>

  <Card title="API契約測試">
    驗證 API
    響應是否符合預期的模式。在收到意外資料結構時快速失敗，而不是嘗試處理它們。
  </Card>

  <Card title="資料庫約束">
    使用資料庫約束（NOT NULL、FOREIGN
    KEY、CHECK）在持久化層強制資料完整性，立即捕获違規。
  </Card>
</CardGroup>

## 經典案例

亞馬遜早期的電子商務架構著名地體現了快速失敗原則。在 1990 年代末，亞馬遜的面向服務的架構要求依賴項不可用時服務快速失敗。服務不會實現複雜的回退邏輯來掩蓋失敗，而是立即向調用者返回錯誤。這種方法雖然最初導致更多可見的失敗，但使亞馬遜團隊能夠快速識別和修復可靠性問題。結果是系統雖然偶爾返回明確的錯誤，但保持了資料完整性，比那些嘗試以降級功能「繼續前進」的系統恢復得更快。這種架構哲學後來成為亞馬遜描述的「從失敗中倒推」的基礎——其雲端計算基礎設施的核心原則。

## 邊界與失效場景

快速失敗原則雖然強大，但需要深思熟慮地應用。首先，並非所有失敗都應該導致立即終止。 在面向使用者的應用程式中，較小的驗證錯誤可能需要友好的錯誤訊息，而不是應用程式崩潰。 該原則最強烈地適用於系統級錯誤，而非所有可能的錯誤情況。

其次，如果錯誤處理不當，快速失敗可能會造成糟糕的使用者體驗。應用程式應在適當的邊界捕获例外，向使用者提供可操作的回饋，而不是技術錯誤傾倒。

第三，在分散式系統中，快速失敗必須與彈性模式相平衡。在每一個短暫的網路瞬間失敗時立即失敗的服務，將比實現適當重試邏輯的服務可用性更低。關鍵在於區分致命失敗（快速失敗是正確的）和暫時失敗（重試可能會成功）。

## 常見誤區

<AccordionGroup>
  <Accordion title="快速失敗意味著讓應用程式崩潰">
    快速失敗是關於有意地、有意義地失敗，而不是造成戲劇性的崩潰。目標是以受控的方式失敗，提供最大的除錯資訊。
  </Accordion>

  <Accordion title="快速失敗始終是最佳方法">
    在面向使用者的應用程式中，優雅降級可能比可見失敗更可取。必須根據使用者體驗考慮來平衡該原則。
  </Accordion>

  <Accordion title="快速失敗消除了錯誤處理的需要">
    快速失敗不會消除錯誤處理——它只是改變了處理發生的位置。應用程式仍然必須在服務邊界適當捕获和回應失敗。
  </Accordion>
</AccordionGroup>

## 相關概念

<CardGroup cols={3}>
  <Card title="防禦性程式設計">
    編寫驗證輸入和假設的程式碼，在不變量被違反時明確失敗。快速失敗是防禦性程式的關鍵技術。
  </Card>

  <Card title="提前返回">
    一種程式碼模式，當前置條件不滿足時函數立即退出，而不是將邏輯嵌套得更深。這在函數層面體現了快速失敗。
  </Card>

  <Card title="斷路器">
    一種彈性模式，停止向失敗的服務發送請求，防止級聯失敗，同時允許系統優雅地恢復。
  </Card>

  <Card title="契約式設計">
    一種方法學，軟體元件指定明確的前置條件、後置條件和不變量。違規立即觸發失敗。
  </Card>

  <Card title="《程式設計師》">
    推廣快速失敗原則的書籍，以及其他軟體開發最佳實踐。
  </Card>
</CardGroup>

## 一句話總結

<Tip>
  快速失敗、明確失敗——當出現問題時，立即停止並保留上下文。修復缺陷的成本隨著未被偵測時間的延長呈指數增長。
</Tip>
