v0.18.17:失敗的檔案列出檔名與原因;補上「上一版說有、其實沒做進畫面」的按鈕
leo Windows 實測 v0.18.16:連線誤報已消失(✅ 那個修正生效), 但出現「⚠ 3 份失敗」→ 加檔後「⚠ 1 份失敗」,兩個新檔沒推上雲端也沒產卡。 ## 修:數字不能代替原因(今天第四次同款病) collector **早就**把「哪個檔失敗、為什麼」寫進 status.json(`Failures[]`), 但 App 一直只讀計數 ⇒ 畫面只會說「⚠ 3 份失敗」 ⇒ leo 只能回報「沒推到雲端」,我只能猜。 前三次同款:exit status 2 蓋掉真話/非文件檔不點名/誤判沒連線。 現在列出檔名+原因(最多 8 份,總數照實講)。 ## 🔴 更正:v0.18.12 宣稱的「一鍵打開紀錄檔資料夾」**根本沒進到畫面** Go 那邊 `OpenLogFolder()`/`EngineTrouble` 都做了,但前端那次 `str.replace()` **錨點縮排不符、沒命中**,而我沒加斷言 ⇒ 檔案沒變,我卻在回覆與 changelog 裡宣稱做好了。 (同一天已經因為「取代沒驗證」出過一次事,這是第二次。) 本次三處錨點**全部 assert**,並機械複驗五個關鍵字+`node --check`。 changelog 也已更正 v0.18.12 那段。 ## 順帶修 .bat 的收集段(leo:「有按照 1 然後 2,你要檢查 bat」) 收集 log 那段用 `>nul 2>&1` **把錯誤全吞掉** ⇒ 失敗了也沒人知道, 我還以為是 leo 沒按 Enter。改成**逐檔回報 v/X/-**,並把輸出目錄 從中文「記錄檔」改成純英文 `logs`(中文路徑+UNC+Big5 主控台三者疊加容易出事)。
This commit is contained in:
@@ -6,5 +6,6 @@
|
||||
"v0.18.13": "fbf7342d0d0e27b4",
|
||||
"v0.18.14": "bfcb4f2701fc23b4",
|
||||
"v0.18.15": "447b59ea3ade430e",
|
||||
"v0.18.16": "12de01a21cd6bf38"
|
||||
"v0.18.16": "12de01a21cd6bf38",
|
||||
"v0.18.17": "c13b08dec6a0fbef"
|
||||
}
|
||||
|
||||
+56
-5
@@ -75,9 +75,17 @@ type directConfig struct {
|
||||
|
||||
// syncStatus 對映 collector 寫的 status.json(只取 UI 要的欄位)。
|
||||
type syncStatus struct {
|
||||
LastSync string `json:"last_sync,omitempty"`
|
||||
ExtractedOK int `json:"extracted_ok"`
|
||||
ExtractFailed int `json:"extract_failed"`
|
||||
LastSync string `json:"last_sync,omitempty"`
|
||||
ExtractedOK int `json:"extracted_ok"`
|
||||
ExtractFailed int `json:"extract_failed"`
|
||||
// 🔴 2026-08-06:collector 早就把「哪個檔失敗、為什麼」寫進 status.json 了
|
||||
// (sync_status.go 的 Failures),但 App 一直只讀計數 ⇒ 畫面只會說「⚠ 3 份失敗」,
|
||||
// 使用者與遠端的我都不知道是哪一份、什麼原因。**今天第四次同款病**
|
||||
// (前三次:exit status 2 蓋掉真話/非文件檔不點名/誤判沒連線)。
|
||||
Failures []struct {
|
||||
Path string `json:"path"`
|
||||
Error string `json:"error"`
|
||||
} `json:"failures"`
|
||||
ExtractorOK bool `json:"extractor_ok"`
|
||||
ExtractorError string `json:"extractor_error,omitempty"`
|
||||
// 「上次真的有做事」那一輪(2026-08-05)——ExtractedOK 是本輪計數、會被下一輪歸零,
|
||||
@@ -228,8 +236,9 @@ type UIState struct {
|
||||
Skipped *UISkipped `json:"skipped"` // 讀不了的檔(沒有就是 null,前端不畫)
|
||||
// EngineTrouble=同步引擎有問題(沒在跑/一直啟動失敗)⇒ 前端才長出「回報問題」卡。
|
||||
// 沒事時不顯示,避免把「哪裡看 log」變成常駐噪音。
|
||||
EngineTrouble bool `json:"engineTrouble"`
|
||||
LogFolder string `json:"logFolder"`
|
||||
EngineTrouble bool `json:"engineTrouble"`
|
||||
Failures *UIFailures `json:"failures"` // 沒有就是 null,前端不畫
|
||||
LogFolder string `json:"logFolder"`
|
||||
}
|
||||
|
||||
// UISkipped=首頁那張「這些檔案現在還處理不了」的卡。
|
||||
@@ -249,6 +258,47 @@ type UISkipped struct {
|
||||
Other string `json:"other"` // 非文件檔的一行說明(沒有就空字串)
|
||||
}
|
||||
|
||||
// UIFailures=首頁那張「有幾份沒送上去」的卡。
|
||||
//
|
||||
// 🔴 存在理由(leo 2026-08-06 實測):畫面寫「⚠ 3 份失敗」但**不說是哪一份、為什麼**
|
||||
// ⇒ leo 只能回報「新的兩個檔案確實沒推到雲端」,我只能猜。
|
||||
// 而原因**本來就在 status.json 裡**,只是沒人拿出來用。
|
||||
type UIFailures struct {
|
||||
Title string `json:"title"`
|
||||
Note string `json:"note"`
|
||||
Items []UIFailItem `json:"items"`
|
||||
More int `json:"more"`
|
||||
}
|
||||
|
||||
type UIFailItem struct {
|
||||
Name string `json:"name"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
// maxFailShown=最多列幾份(多了會洗版;總數仍照實講)。
|
||||
const maxFailShown = 8
|
||||
|
||||
func buildFailures(s syncStatus) *UIFailures {
|
||||
if len(s.Failures) == 0 {
|
||||
return nil
|
||||
}
|
||||
u := &UIFailures{
|
||||
Title: fmt.Sprintf("有 %d 份沒有送進知識庫", len(s.Failures)),
|
||||
Note: "下面是失敗的檔案與原因。這些檔案會自動重試,你不用重丟;如果一直失敗,把這段回報給我們。",
|
||||
}
|
||||
for i, f := range s.Failures {
|
||||
if i >= maxFailShown {
|
||||
u.More = len(s.Failures) - maxFailShown
|
||||
break
|
||||
}
|
||||
u.Items = append(u.Items, UIFailItem{
|
||||
Name: filepath.Base(f.Path),
|
||||
Reason: f.Error,
|
||||
})
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// buildSkipped 把 status.json 的三個欄位翻成首頁看得懂的一張卡。
|
||||
// 完全沒有東西被略過時回 nil ⇒ 前端不畫這張卡(沒事就別佔畫面)。
|
||||
func buildSkipped(s syncStatus) *UISkipped {
|
||||
@@ -377,6 +427,7 @@ func (a *App) GetState() UIState {
|
||||
st.Syncing, st.StatusBig, st.StatusSub = describeStatus(sync)
|
||||
st.Steps = buildSteps(sync, st.Syncing)
|
||||
st.Skipped = buildSkipped(sync)
|
||||
st.Failures = buildFailures(sync)
|
||||
// 引擎有問題才把「回報問題」卡叫出來(含記錄檔路徑)。
|
||||
// 沒事時不顯示——否則「哪裡看 log」會變成常駐噪音,真出事時反而沒人看。
|
||||
st.EngineTrouble = !collectorAlive()
|
||||
|
||||
@@ -72,6 +72,8 @@ function pageHome(s) {
|
||||
</div>`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
${cardTrouble(s)}
|
||||
${cardFailures(s.failures)}
|
||||
${cardSkipped(s.skipped)}
|
||||
<div class="card">
|
||||
<h3>總計</h3>
|
||||
@@ -89,6 +91,42 @@ function pageHome(s) {
|
||||
// 使用者只能得到「我丟了檔,然後什麼都沒發生」這個結論。
|
||||
// 這張卡就是那句話該出現的地方——**首頁**,他每次打開 App 一定會看到。
|
||||
// 沒有東西被略過時後端回 null ⇒ 這裡回空字串,畫面保持乾淨(沒事不佔版面)。
|
||||
// 引擎有問題時才長出來:一鍵打開紀錄檔資料夾。
|
||||
// leo 2026-08-06:「不能用一個 debug mode?」——log 一直都在寫,缺的是入口。
|
||||
function cardTrouble(s) {
|
||||
if (!s.engineTrouble) return '';
|
||||
return `
|
||||
<div class="card">
|
||||
<h3>需要回報這個問題?</h3>
|
||||
<div class="d">
|
||||
詳細的錯誤紀錄已經自動存在你電腦裡,不必開啟任何設定。<br/>
|
||||
把 <b>collector.log</b> 和 <b>app.log</b> 傳給我們就能查。
|
||||
</div>
|
||||
<div class="d" style="margin-top:6px;opacity:.7">${esc(s.logFolder || '')}</div>
|
||||
<div class="acts"><button id="hLogs">打開紀錄檔資料夾</button></div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// 失敗的檔案:列出**檔名與原因**。
|
||||
// leo 2026-08-06 實測:畫面只寫「⚠ 3 份失敗」,他只能回報「沒推到雲端」,
|
||||
// 而原因本來就在 status.json 裡 —— 數字不能代替原因。
|
||||
function cardFailures(f) {
|
||||
if (!f || !f.items || !f.items.length) return '';
|
||||
return `
|
||||
<div class="card">
|
||||
<h3>${esc(f.title)}</h3>
|
||||
<div class="d">${esc(f.note)}</div>
|
||||
<div class="steps" style="margin-top:10px">
|
||||
${f.items.map((it) => `
|
||||
<div class="step">
|
||||
<span class="t">${esc(it.name)}</span>
|
||||
<span class="m">${esc(it.reason)}</span>
|
||||
</div>`).join('')}
|
||||
</div>
|
||||
${f.more > 0 ? `<div class="d" style="margin-top:8px">…還有 ${f.more} 份</div>` : ''}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function cardSkipped(k) {
|
||||
if (!k) return '';
|
||||
return `
|
||||
@@ -214,6 +252,7 @@ function wire() {
|
||||
const on = (id, fn) => { const e = $(id); if (e) e.onclick = fn; };
|
||||
on('uDocs', () => go.OpenURL('https://rag.arcrun.dev/docs/'));
|
||||
on('hLogs', () => go.OpenLogFolder());
|
||||
on('hLogs', () => go.OpenLogFolder());
|
||||
on('hAcct', showConnect); on('obConnect', showConnect);
|
||||
on('obInstall', () => go.OpenURL('https://install.arcrun.dev/'));
|
||||
on('aiSave', saveAI);
|
||||
|
||||
Reference in New Issue
Block a user