跳轉到

MatchRPG 錯誤碼架構澄清與 Dungeon 重新編號(含碰號問題)

文檔資訊

  • 分類: architecture
  • 難度: advanced
  • 預估閱讀時間: 8 分鐘
  • 標籤: error-codes, twirp, dungeon, dead-code, proto, documentation-governance, range-collision

摘要

本次 session 釐清了 MatchRPG Server 的錯誤碼架構為單通道設計(Twirp meta.error_code),確認 commonv1.ErrorCode 是 dead enum,完成 Dungeon 錯誤碼從 1-20 重新編號到 3000-3099,並發現 3000-3099 與通用錯誤碼區段碰號的 P0 問題。同時比對 PD 規格文件與最新設計的差異,識別出語意錯誤和缺漏的 Sticker 模組。

關鍵學習

  • Twirp meta.error_code 是唯一實際使用的錯誤碼通道,proto enum 不做 wire serialization

  • commonv1.ErrorCode enum 是 dead code(0 個 runtime consumer),ErrorHandlingReference.md 描述的是這個死掉的 enum

  • Dungeon 錯誤碼從兩位數 1-20 改到 3000-3099 是安全的(因為 string emit,非 wire integer),但 3000-3099 範圍與 common errors proto 3001-3504 碰號

  • PD 規格 v0.0.20 完全缺少 Sticker 模組(11 個 user-facing codes 5001-5031),且 Dungeon 仍用舊 1-20 編號

  • 文檔治理:TODO_ 前綴可豁免 check-doc-metadata.ps1 lint 檢查

  • 回應應該先讀設計文檔(doc 33)再回答,不能憑假設回答架構問題

技術細節

錯誤碼架構(單通道設計)

MatchRPG Server 的錯誤碼設計是**單通道**:

Twirp Response
  └─ meta.error_code (string) ← 唯一實際使用的通道

pkg/errors/AppError 存在,但只被 HTTP middleware 層使用(auth/idempotency/signature/sequence/ratelimit),是平行的 JSON ErrorResponse 路徑,不是 Twirp meta 的雙層設計。

Dead Code 確認

api/proto/matchrpg/common/v1/errors.protocommonv1.ErrorCode enum: - 0 個 runtime consumer(grep 確認) - ErrorHandlingReference.md(Unity proto repo)描述的是這個死掉的 enum,具有誤導性 - Proto enum integer 不做 wire serialization(只用 string emit),所以重新編號是安全的

Dungeon 重新編號

變更前:Dungeon 錯誤碼 1–20(兩位數,與其他模組格式不一致)

變更後:Dungeon 錯誤碼 3001–3020

// 修改前
NOT_FOUND = 1;
INSUFFICIENT_STAMINA = 2;
// ...

// 修改後
NOT_FOUND = 3001;
INSUFFICIENT_STAMINA = 3002;
// ...

修改了: - api/proto/matchrpg/dungeon/v1/dungeon_errors.proto - internal/modules/dungeon/dungeon_twirp.go(所有 WithMeta("error_code", "N") 字串)

碰號問題(P0)

後來發現3000-3099 範圍與通用錯誤碼碰號: - TODO_pd_error_code_translation.md:214:通用錯誤碼已占用 3001-3504 - api/proto/matchrpg/common/v1/errors.proto:40:雖然是 dead enum,但仍可能誤導維護者

建議:Dungeon 應改到不衝突的區段,需要重新評估。

PD 規格差異

PD_ErrorCode_TranslationSpec.md v0.0.20(2026-03-23)vs doc 33 v2.2(2026-04-07):

差異類型 數量 說明
Sticker 完全缺漏 11 個 5001-5031 不在 PD 規格
Dungeon 舊編號 20 個 仍用 1-20,需改為 3001-3020
P1 語意錯誤 1 個 2032:PD 寫「含非法字元」,實際是長度限制
P2 過於 generic 4 個 2042/2043/2069 等寫「操作失敗請重試」
措辭風格差異 ~10 個 PD/UX 自行決定

What Changed

文檔變更

docs/33_Error_Codes.md 從 v2.0 升版到 v2.2:新增 §6 Sticker 區段(5 個子節),更新 §1.1 range table,§4 Dungeon table 全部從 1-20 更新為 3001-3020,新增 §4.1 舊→新對照表。

新建 docs/TODO_pd_error_code_translation.md:87 個錯誤碼條目(4 個已配置 + 83 個待 PD 配置),9 個子表按模組分類。

程式碼變更

dungeon_errors.protodungeon_twirp.go 完成重新編號,build 和 tests 均通過。pkg/pb/matchrpg/dungeon/v1/dungeon_errors.pb.go(generated file)尚未重新生成,需要 make proto

命名決策

Enums_ResourcesType_PlayerPhysicalStrength = 8 → 改名為 Stamina = 8,新增 EtherHourglass = 9。需要 PD 更新 Luban xlsx。

So What

這次 session 澄清了一個長期存在的架構誤解:commonv1.ErrorCodeErrorHandlingReference.md 描述的是 dead code,不是實際運行的錯誤碼系統。實際系統只有一個通道(Twirp meta.error_code string)。

Dungeon 重新編號雖然完成了,但後來發現 3000-3099 碰號,這是一個需要進一步處理的 P0 問題,不能就此收案。PD 規格的差異分析(特別是 2032 的語意錯誤)如果不修正,會導致用戶看到錯誤的錯誤訊息描述。

Trade-offs

  • 重新編號安全性:因為是 string emit 非 wire integer,重新編號不影響協議相容性;但已生成的 pb.go 和 Unity CS 檔案需要 regenerate
  • 3000-3099 碰號:快速修復時選了一個方便的範圍,但事後發現與通用錯誤碼碰號,需要再次移動
  • Dead enum 保留commonv1.ErrorCode 雖然是 dead code,但刪除前需要確認沒有外部依賴(Unity 客戶端可能有 literal 比對)
  • PD 規格 rebase:建議 PD 直接從 TODO_pd_error_code_translation.md 重新對齊,而非在舊規格上 patch

Try It Fast

# 確認 commonv1.ErrorCode 是否真的沒有 runtime consumer
grep -r 'commonv1\.ErrorCode\|ErrorCode_' internal/ pkg/ cmd/ --include='*.go' | grep -v '_test\.go'

# 確認 Dungeon twirp.go 的錯誤碼已更新
grep 'error_code' internal/modules/dungeon/dungeon_twirp.go

# Build 驗證
go build ./internal/modules/dungeon/...
go test ./internal/modules/dungeon/... -count=1

# 確認 3000-3099 碰號範圍
grep -n '3[0-9][0-9][0-9]' api/proto/matchrpg/common/v1/errors.proto

Recommendation

  1. 立即處理碰號:Dungeon 3000-3099 碰號問題 — 需要選擇不衝突的區段(例如 7000-7099),重新修改 proto、twirp.go 和相關文檔
  2. PD 重新對齊:PD 應以 TODO_pd_error_code_translation.md 為基準重新配置 87 個錯誤碼,特別修正 2032 的語意錯誤(長度限制,不是非法字元)
  3. Proto Regen:從 Windows toolchain 執行 make proto 重新生成 dungeon_errors.pb.go,Unity 端同步 regenerate DungeonErrors.cs
  4. Luban xlsx 更新:PD 將 PlayerPhysicalStrength = 8 改名為 Stamina = 8,新增 EtherHourglass = 9
  5. 未來規範:分配新模組錯誤碼區段前,先 grep 確認範圍無衝突(doc 33 §1.1 range table 是 SoT)

本文檔由 Semi-Brain 自動生成

Session ID: 13536126-c4f1-4c71-ae73-a6544e9167bf

分析信心度: 88%