From 7d41ca50b44b01584ade1454d8c1d28e65e2e62d Mon Sep 17 00:00:00 2001 From: Jeffery Date: Fri, 26 Jun 2026 14:09:40 +0800 Subject: [PATCH] =?UTF-8?q?chore(ai-review):=20=E6=9B=B4=E6=96=B0=20findin?= =?UTF-8?q?gs.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除已修復(categorizeTags 型別防禦)的 finding;保留 6 條錯誤處理/併發/TOCTOU 設計取捨。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitea/ai-review/findings.json | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/.gitea/ai-review/findings.json b/.gitea/ai-review/findings.json index 3c47053..ba0fb4f 100644 --- a/.gitea/ai-review/findings.json +++ b/.gitea/ai-review/findings.json @@ -1,17 +1,21 @@ [ { - "level": "critical", + "level": "warning", "role": "Maya", "location": "app/releases.js:46", - "problem": "清理舊版本成品時,若刪除過程拋出例外或 API 回傳異常(除 204 外),未作完善處理,無法保證一致性且未針對『部分失敗』設計重試或完整性檢查機制。(合併:包含 app/releases.js:46 例外中止問題)", - "suggestion": "將逐筆刪除包在 try/catch,加入錯誤計數;若失敗率過高或發生特定非預期錯誤(如 403),應明確拋出例外讓流程終止。" + "problem": "清理舊版本成品時,若刪除過程拋出例外或 API 回傳異常(除 204 外),未針對「部分失敗」設計重試或完整性檢查機制。", + "suggestion": "將逐筆刪除包在 try/catch 並加入錯誤計數;失敗率過高或遇特定錯誤(如 403)時明確拋例外終止。", + "status": "deferred", + "defer_reason": "錯誤處理/重試/閾值策略的設計取捨。目前 HTTP 失敗(非 204)會記錄並續行、網路層例外則 fail-fast(清理冪等,下次排程補做);是否引入逐筆吞例外、錯誤計數與閾值保留待人工評估。" }, { "level": "warning", "role": "Mage", "location": "app/tags.js:52", - "problem": "cleanupOrphanTags 分兩次 API 呼叫取得 releases 與 tags,過濾過程未保證原子性;期間 Gitea 狀態變更可能誤刪非孤立 tag。(合併:包含 app/tags.js:47, 45 之類似 TOCTOU 風險指控)", - "suggestion": "考量原子性需求,或在刪除前增加確認機制;並明確文件化此風險。建議增加最終防護機制,或在測試中模擬競爭條件。" + "problem": "cleanupOrphanTags 分兩次 API 呼叫取得 releases 與 tags,過濾過程未保證原子性;期間 Gitea 狀態變更可能誤刪非孤立 tag。", + "suggestion": "考量原子性需求,或在刪除前增加確認機制;並明確文件化此風險。", + "status": "deferred", + "defer_reason": "已於 cleanupOrphanTags 以註解明確文件化此 TOCTOU 殘餘競態;現行於開頭重新抓取最新 release 為主要緩解,屬排程任務可接受範圍。完整原子性為一致性/成本設計取捨,保留待人工評估。" }, { "level": "warning", @@ -20,8 +24,7 @@ "problem": "清理流程對網路請求依賴強,若 API 呼叫失敗,整個 main 流程中斷,無法確保後續清理的一致性與部分成功重試。", "suggestion": "引入更細緻的錯誤處理(如錯誤閾值機制)或部分清理成功後的重試策略。", "status": "deferred", - "defer_reason": "錯誤處理/重試策略的設計取捨。目前單筆刪除失敗(非 204)會記錄並繼續、讀取失敗則中止屬合理保守行為;是否引入閾值/重試保留待人工評估。", - "is_new": false + "defer_reason": "錯誤處理/重試策略的設計取捨。目前單筆刪除失敗(非 204)會記錄並繼續、讀取失敗則中止屬合理保守行為;保留待人工評估。" }, { "level": "warning", @@ -30,8 +33,7 @@ "problem": "cleanupReleases 迴圈逐筆 await deleteResource,release 眾多時依序刪除耗時,且 API 負載高時易逾時。", "suggestion": "若 API 允許,採有上限的併發刪除(如限流 Promise.all),或增加進度日誌與重試。", "status": "deferred", - "defer_reason": "刻意保留序列化:避免對 Gitea API 造成併發壓力與觸發速率限制、維持記錄順序,且與原 bash 行為一致;有上限併發/重試屬效能與錯誤處理取捨,保留待人工評估。", - "is_new": false + "defer_reason": "刻意保留序列化:避免對 Gitea API 造成併發壓力與觸發速率限制、維持記錄順序,且與原 bash 行為一致;有上限併發/重試屬效能與錯誤處理取捨,保留待人工評估。" }, { "level": "warning", @@ -40,8 +42,7 @@ "problem": "刪除 tag 的迴圈缺少對 deleteResource 拋例外的防禦,網路錯誤會中止後續 tag 清理。", "suggestion": "在 for 迴圈內加 try/catch,記錄錯誤並 continue;比照 releases 補測試。", "status": "deferred", - "defer_reason": "與 app/releases.js:46 同屬「逐筆吞例外續行 vs fail-fast」的錯誤處理設計取捨;HTTP 失敗已回傳狀態碼並續行,僅網路層例外會中止。保留待人工評估。", - "is_new": false + "defer_reason": "與 app/releases.js:46 同屬「逐筆吞例外續行 vs fail-fast」的錯誤處理設計取捨;HTTP 失敗已回傳狀態碼並續行,僅網路層例外會中止。保留待人工評估。" }, { "level": "warning", @@ -50,14 +51,6 @@ "problem": "deleteResource 僅回傳狀態碼,對 401/403/404 等錯誤未做區分處理。", "suggestion": "在 deleteResource 內針對常見錯誤碼拋出更有意義的例外,讓呼叫方採取跳過/重試/中止策略。", "status": "deferred", - "defer_reason": "現行刻意讓 deleteResource 單純回傳狀態碼、由呼叫端記錄 HTTP code 後續行;依狀態碼分流與重試/閾值同屬錯誤處理設計取捨,保留待人工評估。", - "is_new": false - }, - { - "level": "warning", - "role": "Mage", - "location": "app/tags.js:25", - "problem": "categorizeTags 函式中直接呼叫 keep.has(tag.name),若 API 回傳的 tag 物件缺少 name 欄位或 name 為非字串,可能導致非預期行為。", - "suggestion": "增加明確的型別檢查,確保 tag.name 為 string 後再進行比對。" + "defer_reason": "現行刻意讓 deleteResource 單純回傳狀態碼、由呼叫端記錄 HTTP code 後續行;依狀態碼分流與重試/閾值同屬錯誤處理設計取捨,保留待人工評估。" } ]