昨天把錯誤分成可以 Retry 和應該直接停止之後,我原本以為流程已經安全不少,暫時性的 API Error 可以重新執行,輸入本身有問題就直接停下來,連續失敗也有 Stop Condition,不會再看到 Workflow 一直重跑同一個步驟。
但實際跑了一陣子之後,又冒出另一個很現實的問題,那些重試很多次還是失敗的任務最後去了哪裡?
如果只是把 Workflow 標成 Failed,過幾天再回頭看,很容易只知道某一次執行失敗,卻不知道當時處理的是哪一筆資料、跑到哪一步、前面已經完成哪些事情,甚至連原始 Input 都可能要重新找。
所以今天我沒有再繼續增加 Retry 次數,而是替「真的救不回來的任務」準備一個地方。
我先做了一個很簡單的 Failed Queue,只要一個任務超過允許的 Retry 次數,就不再繼續自動執行,而是把它存進待處理區。
裡面至少記錄幾項資料,包括 Workflow 名稱、Task ID、原始 Input、失敗步驟、Error Message、已經 Retry 幾次,以及最後一次失敗的時間。
如果前面已經有成功完成的步驟,也會一起保存目前的 Checkpoint。
這樣下一次看到失敗任務時,就不用從頭猜「它到底發生什麼事」,因為當時的狀態已經被留下來。
測試的時候剛好碰到一個外部 API 暫時不可用的案例,當下連續 Retry 幾次都失敗,所以任務被放進 Failed Queue,隔了一段時間服務恢復之後,我可以直接從失敗的步驟重新執行,不需要把前面已經完成的資料重新抓一次。
前幾天做的 Checkpoint 到這裡就真的派上用場。
以前我想到「錯誤恢復」時,很直覺會想到 Retry,但 Retry 解決的其實只是短時間內可能恢復的錯誤,真的連續失敗之後,還是需要知道這筆工作現在在哪裡,以及之後能不能重新接回去。
一開始我也想過,既然進 Failed Queue 就全部丟給人來看,但很快發現這樣其實會製造另一種工作量。
有些錯誤只是第三方服務暫時掛掉,隔半小時重新跑一次可能就好了;有些是資料格式錯誤,重新執行一百次也不會成功;還有一些是 AI 輸出的內容沒有通過 Validation,可能重新生成一次就能解決。
所以我開始替 Failed Task 再加一層分類。
暫時性錯誤可以排進稍後重新執行的 Queue,輸入資料本身有問題就標成需要人工處理,涉及權限、付款、刪除資料這類比較敏感的流程則直接停下來,不讓系統自己決定下一步。
這跟昨天的 Retry Classification 很像,只是今天開始處理的是「Retry 已經失敗之後」的世界。
做到現在,我反而沒有那麼追求 Workflow 一定要百分之百成功。
外部服務會掛掉、網路會斷、AI 會產生奇怪輸出,這些事情很難完全消失,比較重要的是失敗之後有沒有留下足夠的資訊,能不能知道哪幾筆工作沒有完成,又能不能從原本的位置接回來。
對我來說,最麻煩的其實不是畫面上跳出一個 Error,而是一個流程看起來每天都有在跑,結果其中幾筆資料早就失敗了,卻完全沒有人知道。
所以今天把 Failed Queue 加進來之後,整套自動化開始多了一個「待處理區」,成功的任務照常往下走,真的救不回來的任務也不會憑空消失。
下一步就很自然了,既然失敗任務都已經被集中起來,我就不想每天自己打開系統檢查,Day 18 我會開始處理通知和 Alert,看看哪些錯誤真的值得馬上叫我,哪些只要先記錄起來就好。