From 857420dfa751553381ee62c3eaef0a843eebd85a Mon Sep 17 00:00:00 2001 From: richblack Date: Thu, 6 Aug 2026 21:41:28 +0800 Subject: [PATCH] =?UTF-8?q?v0.18.18=EF=BC=9A=E5=A4=B1=E6=95=97=E5=8E=9F?= =?UTF-8?q?=E5=9B=A0=E7=9C=9F=E7=9A=84=E9=A1=AF=E7=A4=BA=E5=9C=A8=E7=95=AB?= =?UTF-8?q?=E9=9D=A2=E4=B8=8A=EF=BC=88=E5=89=8D=E9=9D=A2=E5=B9=BE=E7=89=88?= =?UTF-8?q?=E5=8F=AA=E5=81=9A=E4=BA=86=E4=B8=80=E5=8D=8A=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 補完「上游錯誤要看得到」這條線 - 退避中的檔案也進 `status.failures`(先前退避期間該欄是空的 ⇒ 畫面只有「⚠ N 份失敗」沒有原因,等於前面白做) - `shortError` 從 120 放寬到 240 字:真因在訊息**後半段**,砍 120 會整段切掉 ## 實測輸出(不是推測,是印出來的卡片內容) 有 2 份沒有送進知識庫 · 2021超新星品牌白皮書-科特勒.pdf 今天的免費 AI 額度用完了 ⇒ 明天會自動恢復,這些檔案會自己補上,你不用做什麼。 · 台灣青年創新創業協會謝侑霖.pdf 這份 PDF 看起來是掃描的圖片 ⇒ 需要先做文字辨識(OCR),或換一份有文字的版本。 ⇒ 同樣是「失敗」,處置完全相反(等就好/要動手),使用者現在分得出來。 (測試資料取自 leo Windows collector.log 的原文。) --- cmd/arcrun-app/.version-source.json | 3 ++- direct.go | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/cmd/arcrun-app/.version-source.json b/cmd/arcrun-app/.version-source.json index 3cc4549..5aacbec 100644 --- a/cmd/arcrun-app/.version-source.json +++ b/cmd/arcrun-app/.version-source.json @@ -1,4 +1,5 @@ { "_algo": 2, - "v0.18.17": "cb6e53a052b87482" + "v0.18.17": "cb6e53a052b87482", + "v0.18.18": "a495451d9d9da78a" } diff --git a/direct.go b/direct.go index 12f1235..a4b9540 100644 --- a/direct.go +++ b/direct.go @@ -685,6 +685,17 @@ func RunDirectOnce(cfg *DirectConfig, dryRun bool) ([]DirectResult, int, *Trigge Path: r.Path, Error: shortError(r.Error), }) + case "skipped": + // 🔴 leo 2026-08-06:退避期間這個檔**不會**再產生 "failed", + // 於是 status.failures 是空的 ⇒ 畫面只剩「⚠ N 份失敗」沒有原因。 + // 退避訊息裡已經帶了上游真因(retrySkipReason),一併收進來, + // 使用者才看得到「為什麼」而不只是「幾份」。 + if strings.Contains(r.Error, "後重試") || strings.Contains(r.Error, "已暫停自動重試") { + st.Failures = append(st.Failures, ExtractFail{ + Path: r.Path, + Error: shortError(r.Error), + }) + } } } } @@ -711,12 +722,21 @@ func RunDirectOnce(cfg *DirectConfig, dryRun bool) ([]DirectResult, int, *Trigge } // shortError 把錯誤字串截為一句話(供 UI 顯示,不要超過 120 字)。 +// shortError 限制錯誤訊息長度。 +// +// 🔴 2026-08-06 放寬到 240:訊息現在會**帶上游真因** +// +// (「上次失敗(第 4 次),58m 後重試|原因:…Workers AI…4006: you have used up +// your daily free allocation of 10,000 neurons…」), +// 而真因在**後半段**——砍 120 會把它整段切掉,等於又回到「只說失敗不說原因」。 +// (leo 原則:別人的錯誤一律要顯示給用戶看。) func shortError(msg string) string { - if len([]rune(msg)) <= 120 { + const max = 240 + if len([]rune(msg)) <= max { return msg } runes := []rune(msg) - return string(runes[:120]) + "…" + return string(runes[:max]) + "…" } // CheckExtractor 預檢萃取器是否可用(不執行萃取、不打 API)。