公告:n8n 的 Continue On Fail 會默默吞掉節點錯誤 — 你的執行日誌在欺騙你

這是我在生產環境的 n8n 工作流程中經常看到的問題,讓人很容易踩坑。

當你在節點上啟用「失敗時繼續」(Continue On Fail) 時,n8n 即使該節點因為 500、401 或空回應而失敗,仍然會將執行標記為成功。錯誤會以錯誤輸出資料的形式傳遞到下游,工作流程會繼續執行,而頂級執行狀態顯示為綠色。

這意味著:你的 HubSpot 節點失敗了、CRM 列從未建立、客戶從未收到電子郵件 — 而 n8n 的執行日誌卻顯示成功。

這造成實際問題的三個地方:

  1. 使用「失敗時繼續」的 HTTP Request 節點 — API 返回 500 看起來與執行檢視中的 200 完全相同

  2. 拋出錯誤的代碼節點 — 以無聲方式傳遞到下游

  3. 多步驟流程中的任何節點,你「只想讓它繼續執行」

解決方法是在任何使用「失敗時繼續」的關鍵節點後添加一個明確的 IF 節點 — 檢查輸出中是否存在 $json.error,並將其路由到警報分支。

有人在生產環境中遇過這個問題嗎?很想知道大家是如何在較大的工作流程中處理這個問題的。

很好的補充。不一致的錯誤形狀確實會一直困擾人們。在同一個 IF 檢查中同時處理 $json.error.message 和 $json.error 純字串的做法是正確的。

零項目的情況在某些方面比 CoF 更棘手。沒有錯誤形狀,流程只是停止,上游的一切都顯示綠色。我在輸出為空確實代表失敗的節點上新增明確的項目計數檢查,而不只是安靜地處理邊界情況。

關於設定:中央 Error Trigger 用於明顯的失敗,但這留下了 CoF 和零項目的情況未被涵蓋。一直在建構專門用於綠色但損壞的模式的東西。你在生產環境中最常看到零項目在哪個地方咬人?

在生產環境中遇過在客戶端報表工作流程出現這種狀況。inline IF-after-CoF 模式可行,但有個結構上的弱點:每個檢查都存在它正在檢查的工作流程內部。如果流程提前停止(你的零項目情況),或有人編輯一個節點並刪除檢查分支,驗證就會隨之消失——而上游的所有內容仍然顯示為綠色。

我最後採用的方案:保留 inline 檢查用於路由,但把健康狀況驗證移到工作流程外部。每個生產工作流程在最後一步寫一行執行中繼資料(狀態、項目數、時間戳記)到日誌工作表;一個獨立的排程監控器讀取日誌,並在缺少執行、錯誤列或零計數輸出時發出警報。監控器能夠應對在它監控的工作流程內發生的任何情況——包括根本不執行,這是任何 inline 檢查永遠無法捕捉的。

好奇這在什麼規模時會開始對人們造成傷害——當你建立 CoF 紀律時,正在執行多少個生產工作流程?

@dima_automation 對於生產環境中零項目咬合問題——我最常看到的地方是 Google Sheets「取得列」,使用傳回空值的篩選條件(過期的令牌、工作表已重新命名、範圍錯誤)。工作流程執行順利,產生零項目,每個下游節點都產生零項目,最終的傳送/寫入節點就是永遠不執行。沒有錯誤、綠色日誌、客戶端收不到報告。第二常見的:HTTP Request 節點分頁提前退出,因為 API 更改了回應架構,而「還有更多頁面」檢查傳回 false。我使用的修復方法:在任何零輸出會造成真正失敗的節點之後,新增一個 IF 節點檢查 {{ $items().length === 0 }},並將其路由到明確的警報,而不是無聲地繼續。

這兩種情況都是教科書級別的,特別是那個帶有篩選條件、悄悄不匹配任何結果的「試算表取得列」節點,下游全是零,最後的傳送永遠不會執行,日誌是綠色的。這是我見過對整個問題最乾淨的說明。

檢查 {{ $items().length === 0 }} 的 IF 節點是正確的流程內防護,其中零明確代表失敗。有一點值得標記:它捕捉了你的第一種情況,但不是第二種。提前分頁退出會返回一個截斷但非零的集合,所以 length === 0 會直接滑過,流程得到了 200 列中的 40 列,每個節點都開心地非空。那種情況需要一個預期計數或基準檢查,大致上是檢查這次執行的結果是否遠低於這次執行通常產生的結果,而不僅僅是零與非零。

這兩種模式仍然都假設執行觸發了。最糟糕的版本是排程工作流根本沒有觸發,沒有 IF 節點執行因為什麼都沒運行,沒有什麼讀作零因為什麼都沒執行。這就是促使我傾向於從外部檢查執行結果的情況,單節點防護無法守護沒發生的執行。你的零檢查加上計數基準加上外部活動檢查涵蓋了它們之間的大部分情況。