第 17 章

錯誤處理:Error workflow / Retry / Wait

上線後的 workflow 半夜掛了,不會有人自動告訴你——除非你事先鋪好接住錯誤的網。這章教三件事:讓整條 workflow 掛的時候 Slack 通知你(Error workflow)、讓單一節點暫時失敗時自動重試(Retry on fail)、以及故意等一下避開 API 打太快被封鎖(Wait 節點)。做完,你的 workflow 才算「真的可以放著跑」。

為什麼上線前一定要接錯誤處理

第 10 章教你把 workflow 從 Manual 換成 Schedule,讓它每天早上 8:00 自動跑;第 16 章教你分流、合流、切批次。看起來 workflow 已經很聰明——直到某一天你發現:

  • 週一早上 9 點:老闆問「上週的日報怎麼沒發?」你打開一看,Schedule 上禮拜三就悄悄失敗了,沒人知道。
  • 發薪日:workflow 一次呼叫外部 API 100 次,被對方判 rate limit 擋掉一半,結果一半的人沒收到通知。
  • 某個星期六凌晨:對方系統打嗝 30 秒,你的 workflow 剛好那時候跑,一次失敗——但其實只要重試一次就會成功。

這三種情境,n8n 都有現成的解法:Error workflow 接第一種、Retry 接第三種、Wait 接第二種。它們不是三選一,是 Production workflow 該同時有的三層保險——通知你錯了、單點自救、避免打死對方。這章一次講完,之後你的 workflow 才算「上線 grade」。

觀念:錯誤處理不是「等真的出錯再說」,而是寫 workflow 的當下就順手加。你事後才想要補 Error workflow,通常已經漏了三次通知了。

三種錯誤處理各管什麼

先把三張牌攤開——名字很像,管的層級完全不同:

機制接住什麼層級的錯做什麼什麼時候用
Error workflow 整條 workflow 掛(任何節點死到底) 觸發另一條專門處理錯誤的 workflow(例:Slack 通知你) 每一條 production workflow 都該綁
Retry on fail(節點層) 單一節點失敗(例:某個 HTTP Request 掛) 該節點自動重試 N 次,中間隔一段時間 API 偶爾抽風、網路 blip、輕微 rate limit
Wait 節點 不是接錯——是預防錯 workflow 停在這裡等 X 秒/等到某個時間/等外部 callback 避免打太快被 rate limit、要間隔通知、等對方系統處理完

三者關係:Wait 是事前預防、Retry 是事中自救、Error workflow 是事後補救。一條上線的 workflow 三個都該有,缺一個就少一層防線。

提示:初學者常搞混:Retry 是「這一個節點自己重試」;Error workflow 是「整條 workflow 已經放棄了才觸發」。Retry 5 次都失敗 → workflow 掛 → Error workflow 才會被叫起來。

Error workflow 是什麼——一條專門接錯誤的 workflow

Error workflow 是另外一條獨立的 workflow——不是設定,是一整條 workflow。它跟你平常的 workflow 一樣,只是它的第一個節點必須是 Error Trigger。

運作邏輯是這樣的:

  1. 你先做一條 Error workflow

    用 Error Trigger 當第一個節點,後面接 Slack / Email / Discord / 資料庫,做「發生錯誤時要通知誰/記到哪」。

  2. 其他 workflow 各自「指定」用這一條當 Error workflow

    每條 production workflow 在 Settings 裡選 Error Workflow = 剛剛那條。

  3. 某條 workflow 出錯 → n8n 自動觸發 Error workflow

    Error Trigger 節點會收到出錯 workflow 的名字、時間、錯誤訊息、掛在哪一個節點等資料,交給下游節點處理。

Error Trigger 節點會把錯誤資訊塞到 $json,常用欄位:

欄位意思Expression 寫法
出錯的 workflow 名字 是哪條 workflow 掛了 {{ $json.workflow.name }}
出錯的 workflow ID 方便點連結進去看 {{ $json.workflow.id }}
錯誤訊息 n8n 給的錯誤描述 {{ $json.execution.error.message }}
掛在哪一個節點 是哪個節點死的 {{ $json.execution.lastNodeExecuted }}
Execution URL 直接點進去看該次執行紀錄 {{ $json.execution.url }}
注意:Error Trigger 節點只會因為「別條 自動觸發 workflow 掛」而被叫起(Schedule/Webhook/Event Trigger);你按 Execute Workflow 手動跑 Error workflow、或手動跑的主 workflow 掛,都不會啟動 Error Trigger(官方明說「You can't test error workflows when running workflows manually」)。要測試,先把一條「一定會錯」的 workflow 設 Active + Schedule 讓它自動跑一次掛。
隱藏 default:官方文件補了一條容易忽略的行為——「If a workflow contains the Error Trigger node, by default, the workflow uses itself as the error workflow」。意思是:含 Error Trigger 節點的 workflow,如果它自己也 Active 且會被自動觸發,它出錯時預設會呼叫自己。所以你的 Error Handler workflow 不要再放 Schedule/Webhook Trigger(會造成 self-reference 混亂)——只留 Error Trigger 一個 trigger 就好。

動手做:建一條全公司共用的 Error workflow

目標:做一條 Error Handler workflow,出錯時自動貼一則訊息到 Slack 的 #alerts 頻道。設一次,之後所有 workflow 都用它。

  1. 建新 workflow,命名 Error Handler

    左側 Workflows → + Add workflow。畫布空白後,先按 Ctrl+S 存檔,名字打 Error Handler——名字取有辨識度的,之後在 Settings 下拉才找得到。

  2. 加 Error Trigger 節點

    Canvas 空白處按 Tab(或左上 + 號)叫出節點抽屜 → 搜尋 Error Trigger → 選它。它會落到 canvas 上,作為這條 workflow 的起點。Error Trigger 沒有任何參數要設,放上去就好。

  3. 加 Slack 節點接在後面

    Error Trigger 右邊拖出線,落點放開叫節點抽屜 → 搜尋 Slack → 選 Send a message action。第 7 章如果還沒設過 Slack credential 就先設一個(OAuth 授權 Slack workspace)。

  4. Slack 節點參數:Channel 填 #alerts

    Channel 欄可以用 By Name 選現有頻道,或直接打 #alerts。這個頻道要先在 Slack 建好,並且把 n8n bot 邀請進去(Slack 頻道 → Integrations → Add App)。

  5. Slack 訊息內容(用 Expression 塞錯誤資料)

    Text 欄切到 Expression 模式(點欄位右上的 fx),貼上:

    ⚠️ Workflow 錯誤通知
    Workflow: {{ $json.workflow.name }}
    掛在節點: {{ $json.execution.lastNodeExecuted }}
    錯誤訊息: {{ $json.execution.error.message }}
    時間: {{ $json.execution.startedAt }}
    點這裡看: {{ $json.execution.url }}

    底下的 preview 會顯示假資料樣本,看起來對就 OK。

  6. Save,然後把右上 Active toggle 拉成綠色

    按 Ctrl+S → Active toggle ON。Error workflow 沒 Active 是不會被觸發的——這是第一名踩雷。

  7. 做完了——這條之後全公司共用

    Error Handler workflow 設完就放著,不用天天管。它只在別條 workflow 出錯時被叫起來執行一次,沒事的時候完全不佔資源。

提示:如果你的團隊有 PagerDuty / Opsgenie / Email,可以在 Slack 節點後面再串 Email 或用 IF 節點判斷「嚴重度」——特定 workflow(例:計費相關)出錯就同時打電話、其他 workflow 出錯只發 Slack。這條 Error Handler 就是你的錯誤中央處理室,愛加什麼都行。

每條 workflow 綁定 Error workflow

Error Handler 建好之後,還要逐一去每一條 production workflow 指定它——不指定的話出錯還是沒人管。

  1. 打開你要監控的 workflow

    從 Workflows 清單點進去,畫布會展開。

  2. 右上角三點選單 → Settings(或按 Ctrl+,)

    會彈出 Workflow Settings 面板,裡面有 Timezone、Save Failed Executions、Error Workflow 等選項。

  3. Error Workflow 下拉選 Error Handler

    下拉會列出你這個 instance 上所有包含 Error Trigger 節點的 workflow。找到 Error Handler 點下去。

  4. Save Settings

    面板右下 Save。之後這條 workflow 出錯就會自動觸發 Error Handler。

  5. 把所有 production workflow 都設一遍

    不會自動套用——每條 workflow 都要各自指定。可以列個清單一次做完,之後新增的 workflow 也記得順手設。

注意:Error workflow 是「被指定的那條 workflow 出錯時才觸發」;Error Handler 這條 workflow自己出錯,是不會遞迴觸發自己的(不然就無窮迴圈了)。所以 Error Handler 內部的節點失敗,是完全沒人接的——把 Error Handler 做得簡單、少依賴,是很重要的守則。

節點層 Retry on fail:讓單一節點自己重試

Retry on fail 是設在單一節點上的自動重試機制——這個節點失敗時,n8n 會等一下再打一次、再等一下再打一次,重試次數用完才判定失敗。適合對付「短暫性錯誤」(transient error):API 暫時 503、網路抖一下、對方系統重啟中。

怎麼設

  1. 打開你想重試的節點面板

    例:HTTP Request 節點、Slack 節點、Google Sheets 節點——任何節點都能設。

  2. 切到 Settings tab

    節點面板頂端有 Parameters / Settings 兩個 tab,點 Settings。

  3. Retry On Fail 切成 ON

    會展開兩個新欄位:Max Tries 與 Wait Between Tries。

  4. Max Tries 填重試次數(含首次執行)

    常用值 3—5。填 3 代表最多打三次(第 1 次失敗、等一下、第 2 次失敗、等一下、第 3 次失敗才判死)。

  5. Wait Between Tries 填毫秒數

    常用值 1000(1 秒)到 5000(5 秒)。太短沒等對方系統喘息、太長 workflow 拖很久。API rate limit 錯誤建議 5000 以上。

什麼場景適合開 Retry

場景適不適合 Retry為什麼
API 回 503 Service Unavailable 非常適合 對方服務暫時掛掉,過幾秒通常會恢復
API 回 429 Too Many Requests(rate limit) 適合(配合 Wait Between Tries 拉長) 等一下就解鎖
Network timeout/連線失敗 適合 網路 blip 通常瞬間就過
API 回 401 Unauthorized(credential 過期) 不適合 再打 100 次也一樣過期,浪費時間;該去重新授權 credential
API 回 404 Not Found(資料真的不存在) 不適合 資料就是沒有,重試也生不出來
你的 Expression 寫錯(undefined 之類) 不適合 邏輯錯誤不會因為重試就變對
注意:Retry 會把該節點的操作重複執行——如果那個節點是「寄信」「建立訂單」「扣款」,Retry 就會重複寄/重複建/重複扣。這叫做「非冪等(non-idempotent)」問題。開 Retry 前先想:「這個操作再做一次會不會有副作用?」有副作用的節點,要嘛不開 Retry、要嘛用「先查在不在、不在才建」的守衛邏輯。

Wait 節點:故意停一段時間

Wait 節點做一件很簡單的事——讓 workflow 停在這裡,時間到了才往下走。用來降速、對齊時間、或等外部系統回話。

Wait 有三種模式

Resume 模式什麼時候繼續典型場景
After Time Interval 等 X 秒/分/小時/天 每一批間隔 1 秒避免打太快、發通知後等 10 分鐘再檢查狀態
At Specified Time 等到某個特定日期時間(例:2026-08-20 09:00) 「明天早上 9:00 再繼續」「下個月 1 號才發帳單」
On Webhook Call 等外部系統打 webhook 回來才繼續 發送簽核連結 → 等對方點了才繼續;發起金流 → 等對方 callback 才確認

最常用的 pattern:Wait 配 Split In Batches 避免 rate limit

假設你要對 500 筆資料呼叫外部 API,一次全打會被 rate limit 擋。改成:Split In Batches(batch size = 10)→ HTTP Request → Wait 1 second → 回到 Split In Batches 下一批。這樣每秒 10 個 request,通常都在對方 rate limit 允許範圍內。第 16 章有完整例子。

觀念:Wait 期間 workflow 是「掛著」的——不佔 CPU、只佔一點記憶體。所以 Wait 幾小時、幾天都不會爆你的伺服器。它跟「用 setTimeout 卡在 code 裡」不一樣,是 n8n 內建的 pause 機制。
釐清一個常見誤解(65 秒不是上限):網路上有人講「Wait 最多 65 秒」——錯的。官方文件的原話是「wait times less than 65 seconds, the workflow doesn't offload execution data to the database」,意思是65 秒是「切換執行機制」的門檻,不是最大值:< 65 秒 workflow 掛在記憶體、不寫 DB;≥ 65 秒 n8n 把 execution 序列化存進 DB,時間到再喚醒。Community 版一樣支援 Wait 幾小時、幾天,甚至 At Specified Time 等到下個月。唯一風險:超過 65 秒改走 DB 路徑後,如果 n8n 只用預設 SQLite,重啟或 DB 損毀會遺失待喚醒 execution——長 Wait 建議搭配 Postgres/MySQL 外部 DB。
補充第四個模式:Wait 節點還有一個 On Form Submitted 模式——workflow 停在這裡等使用者送出 n8n 產生的表單才繼續(審核/收集資料場景)。上表列的是最常用三個,Form 屬進階,熟 Webhook 後再學。

Executions 紀錄與 debug

錯誤處理接住了、通知發出去了——接下來你要做的事是打開 Executions 頁面看到底是哪個節點、什麼原因掛的。Executions 頁是你 debug workflow 的主戰場。

Executions 頁在哪

  • 全域:左側主導覽 Executions,看整個 instance 所有 workflow 的執行紀錄。
  • 單一 workflow:進入某條 workflow → 頂端 Executions tab,只看這條的。

怎麼讀紀錄

顏色/圖示意思
綠色 Success 所有節點都跑完,沒錯
紅色 Error 中途有節點掛了,workflow 沒跑完
橘/黃色 Running 正在跑(例:Wait 節點在等)
灰色 Waiting Waiting for webhook 或 At Specified Time 等外部條件

點任一筆紅色 Execution 進去 → 會看到 canvas 樣的視覺化:失敗的節點會被紅框 highlight,點該節點就看到當時的 input / output / error 訊息。這是找 bug 最快的方式。

Executions 頁面顯示成功與失敗的執行紀錄
圖 17-1Executions 頁面:綠色是成功、紅色是失敗,點紅色那筆進去就能看到掛在哪個節點跟錯誤訊息。

Pin data:測試時很好用的省 API 次數招

開發時每改一個節點就重跑一次 workflow,會不斷打真的 API(Gmail、Slack、Sheets),既慢又浪費 quota。Pin data 可以讓你把某個節點的一次成功 output 釘住,之後 workflow 重跑到那個節點時,會直接吃 pin 住的資料,不會真的打 API。

用法:跑一次成功 → 點該節點的 output → 上面有個「圖釘」icon → 按下去,output 就固定了。改完下游要看效果,重跑 workflow,pinned 節點會直接吐 pinned 資料。開發完取消 pin 再上線。

提示:Executions 頁只保留最近幾天(依 Instance 的 EXECUTIONS_DATA_MAX_AGE 環境變數,預設 336 小時 = 14 天)。想留久一點請找 IT 調;或者你在 Error Handler 裡順手把錯誤寫到 Google Sheets / DB,就永久留底了。

常見錯誤情境對照

把最常遇到的錯誤跟建議做法列個對照,你之後看到某個錯誤訊息可以直接查怎麼救:

錯誤情境該用什麼做法
429 Too Many Requests(打太快) Wait + Retry Wait 節點降速;該節點 Retry on fail 開,Wait Between Tries 拉到 5000ms 以上
503 Service Unavailable / 短暫網路錯 Retry Max Tries = 3~5,Wait Between Tries = 2000ms
401 Unauthorized(credential 過期) Error workflow(通知你手動處理) Retry 沒用;靠 Error workflow 通知 → 你去 Credentials 頁面重新授權
Network timeout Retry + Wait Retry on fail + Wait 5s,避免立刻再打一次時對方還沒恢復
資料格式錯(Expression undefined) 前面加 Set 或 IF 節點驗證 Retry 沒用(邏輯錯),要在資料進來時就用 Set 給預設值、或 IF 過濾
Sub-workflow not found Error workflow 通知 Sub-workflow 被刪或 ID 改了;通知你去修 Execute Workflow 節點的引用
Webhook Trigger 沒收到 Error workflow 抓不到(不算錯)+ 主動 Schedule 檢查 Webhook 沒被打不會觸發任何錯誤;加一條 Schedule workflow 每小時檢查「上小時應該有幾筆」
Gmail Trigger poll 太慢 不是錯,是設計問題 把 Poll Times 改成 Every Minute;真要即時就找有 push webhook 的服務

錯誤處理常見卡關

設完錯誤處理,你可能會遇到「明明設了但沒動」的狀況。這幾種對照一下八成能自己救:

症狀可能原因怎麼救
workflow 掛了但 Error workflow 沒觸發 (1) 該 workflow 的 Settings 沒指定 Error Workflow
(2) Error Handler 這條 workflow 沒 Active
回到出錯 workflow → Settings → Error Workflow 下拉選 Error Handler;再去 Error Handler workflow 確認右上 Active 是綠的
Retry 5 次還是全部失敗 錯誤根本不是暫時性的(credential 過期、資料本來就不對、邏輯錯) Retry 只延遲失敗、不會解決根本問題。看 Executions 的錯誤訊息,是 401/400/404/JS error 就別靠 Retry,去修根本原因
Wait 節點 workflow 一直停不動 (1) On Webhook Call 模式但對方沒打 URL 回來、(2) 超過 65 秒 Wait 用 SQLite 遇到重啟遺失了、(3) At Specified Time 時區設錯(跟 workflow Settings 的 Timezone 差 8 小時) 檢查給對方的 webhook URL 是否正確、對方端有沒有真的觸發 callback;長 Wait 換 Postgres 外部 DB;At Specified Time 對照 Settings → Timezone
Executions 頁看不到剛剛跑的紀錄 (1) 頁面沒 refresh、(2) workflow 剛 Active 但 Schedule 還沒到、(3) Executions 保留天數已過 按瀏覽器 F5;確認 Schedule 下次時間到了沒;管理員看 EXECUTIONS_DATA_MAX_AGE 是不是被調短
Error workflow Slack 訊息內容都是 undefined Expression 打錯欄位路徑 Error Trigger 節點跑一次(用一條真的會錯的 workflow 觸發),看 output 面板實際 $json 長什麼樣,照著抄欄位
Error workflow 自己也掛了(Slack 節點失敗) Error Handler 沒有再上一層錯誤處理(本來就不會遞迴) Error Handler 保持簡單、少依賴(避免用容易掛的 API);重要用途可以在 Error Handler 內加第二種通知(例:Slack 失敗就寄 Email backup)
開了 Retry 之後發現重複寄了 3 封信 該節點是非冪等操作,重試 = 重複執行副作用 寄信/建單這類節點關掉 Retry,改在前面加一個「先查有沒有」的節點;或該節點失敗就整條 workflow 失敗,走 Error workflow 通知你手動處理
Error Workflow 下拉是空的,找不到 Error Handler 你的 Error Handler workflow 裡沒有 Error Trigger 節點 回去 Error Handler,確認第一個節點是 Error Trigger(不是 Manual、不是 Webhook)。n8n 只把「含 Error Trigger 節點」的 workflow 列在下拉裡

常見問題

一定要有 Error workflow 嗎?
Production(正式上線、有人依賴的)workflow 強烈建議一定要有,不然出錯真的沒人知道;開發/測試階段可以先跳過,你在 canvas 上手動跑就會馬上看到錯。判斷準則:這條 workflow 掛掉會不會影響到其他人?——會,就綁 Error workflow;只是自己一次性任務,Manual Trigger 手動跑,掛就掛,可以先跳過。
Retry 會不會導致重複執行、產生副作用(例:寄兩封信、扣兩次款)?
會!這是最常被忽略的坑。Retry 是從失敗的那個節點原封不動再打一次——如果那個節點是「寄信」「建訂單」「扣款」,Retry 就會重複做。專業術語叫「非冪等(non-idempotent)」問題。設計原則:只在對方 API 本身冪等(同一份 request 打幾次結果都一樣,例如「查資料」「更新資料」)時才開 Retry;「建立資料」「觸發動作」類的節點,要嘛不開 Retry,要嘛前面加「先查在不在」的守衛節點。
Wait 節點消耗資源嗎?可以 Wait 一整天嗎?
很省。Wait 期間 workflow 是「掛起」的,不佔 CPU、只佔一點記憶體(execution 上下文序列化存在 DB)。Wait 一整天甚至一週都沒問題。但注意:n8n 重啟時(更新版本、伺服器重開機),存活中的 Wait 執行會被恢復繼續等——前提是 n8n 有正常寫 DB。self-hosted 沒設 external DB 只用 SQLite 的話,Wait 幾天以上遇到重啟風險比較高,重要用途建議用 At Specified Time 模式,或改成「存資料到外部 DB + 另一條 Schedule 掃」。
多條 workflow 能共用同一個 Error workflow 嗎?
可以,強烈推薦。你不需要每條 workflow 各做一個 Error workflow——一個 Error Handler 服務全公司 100 條 workflow 都沒問題。訊息裡用 {{ $json.workflow.name }} 就能顯示是哪條掛的。唯一例外:如果某類 workflow 的錯誤要通知不同的人(例:計費 workflow 通知財務、營運 workflow 通知客服),可以做兩三條 Error workflow 分別綁不同對象。
Error workflow 自己掛了會怎樣?
會安靜地掛掉,沒有人接(n8n 不會遞迴觸發 Error workflow 自己的錯誤,不然就無窮迴圈)。所以 Error Handler 要做得盡量簡單、少依賴脆弱的第三方 API。想更保險的做法:Error Handler 裡放兩種通知(Slack + Email),任一種通道故障另一種還能救。或者你另外設一條 Schedule 「每天早上 8:00 檢查昨天有沒有錯誤紀錄」,作為 backup 兜底。
「Continue On Fail」是什麼?跟 Retry 有什麼不一樣?
節點 Settings 除了 Retry On Fail,還有一個 On Error 選項(舊版叫 Continue On Fail),意思是:這個節點失敗時,不要讓整條 workflow 掛,而是繼續往下跑。三個選項:Stop Workflow(預設,會掛)、Continue(節點掛但吐空資料繼續走)、Continue (using error output)(節點多長一條 error 分支,錯誤資料走那條)。Continue On Fail 適合「這個節點失敗沒關係,可以繼續」的場景——例:批次處理 100 個客戶,其中 3 個失敗,剩下 97 個還是要處理完。跟 Retry 可以並用:先 Retry 3 次還是失敗,再走 Continue 繼續下一批。
Error workflow 只在 Active workflow 觸發嗎?我手動 Execute Workflow 掛也算嗎?
官方文件講得很直接:「You can't test error workflows when running workflows manually. The Error Trigger only runs when an automatic workflow errors.」——手動 Execute Workflow 掛絕對不會觸發 Error Trigger,這不是選項、是硬規則。所以要測試 Error workflow,一定要:(1) 把主 workflow 設成 Active、(2) 用 Schedule/Webhook/Event Trigger 讓它「自動」跑起來、(3) 讓它真的失敗。這是刻意設計避免開發時被 Slack 轟炸,但也代表你沒辦法在 canvas 上按按鈕測 Error workflow——只能靠一條真的會錯的 Active workflow 觸發它。
Wait 節點的 On Webhook Call 模式怎麼用?
用來做「等外部確認」的 workflow。設定後 Wait 節點會產生一個 URL(Test 與 Production 各一),workflow 跑到這裡會停下來等這個 URL 被打。典型場景:workflow 發送簽核連結 email,email 裡的按鈕連到 Wait 的 URL——主管點按鈕 → Wait 節點收到 webhook → workflow 繼續往下跑「已簽核」的邏輯。這是進階用法,一般人先熟 After Time Interval 就夠;細節可以搭配第 22 章的 Webhook 概念一起讀。
錯誤處理設完之後還要做什麼?
兩件事:(1) 定期看 Executions 頁——就算 Error workflow 有通知,紅色紀錄還是要定期看趨勢(是不是某個節點反覆失敗?是不是某段時間 rate limit 特別多?)。(2) 建錯誤清單常識庫——遇到某個特殊錯誤解決之後,把「錯誤訊息 → 原因 → 解法」記下來,下次同樣錯直接查。附錄的錯誤訊息速查就是幫你整理常見錯誤的參考。