-
Notifications
You must be signed in to change notification settings - Fork 0
errors.md
maoxiaoyue edited this page May 14, 2026
·
2 revisions
預定義結構化錯誤碼系統,讓 AI 和人都能一致理解和使用錯誤。
傳統做法每個 handler 各自定義錯誤訊息,AI 無法預測回傳格式。Typed Error Catalog 將錯誤定義為全域常數,統一格式且可被 Manifest 收錄:
❌ c.JSON(404, map[string]string{"error": "user not found"}) ← 隨意格式
✅ errors.AbortWithAppError(c, errors.ErrUserNotFound.With("id", 42)) ← 結構化
package apperrors import "github.com/maoxiaoyue/hypgo/pkg/errors" var ( ErrUserNotFound = errors.Define("E1001", 404, "User not found", "users") ErrUserExists = errors.Define("E1002", 409, "User already exists", "users") ErrInvalidEmail = errors.Define("E1003", 422, "Invalid email format", "users") )
func getUser(c *hypcontext.Context) { id := c.Param("id") user, err := userService.FindByID(id) if err != nil { errors.AbortWithAppError(c, apperrors.ErrUserNotFound.With("id", id)) return } c.JSON(200, user) }
{
"code": "E1001",
"message": "User not found",
"details": {
"id": "42"
}
}errors.Define(code, httpStatus, message, category) *AppError
自動註冊到全域 Catalog,通常在 package-level var 區塊中使用。
// 附加上下文(回傳副本,原始不變) err.With("field", "email") err.WithDetail("reason", "already exists") err.WithDetails(map[string]any{"a": 1, "b": 2}) err.WithMessage("Custom message") // 轉為 JSON(給 HTTP response 用) err.JSON() // → map[string]any{"code":"E1001","message":"...","details":{...}} // 錯誤比對(只比 Code,忽略 Details) errors.Is(err1, err2) // true if same code
// 中斷請求並回傳結構化錯誤 errors.AbortWithAppError(c, err) // 回傳錯誤但不中斷 middleware 鏈 errors.RespondError(c, err)
catalog := errors.GlobalCatalog() // 查詢所有已定義的錯誤 all := catalog.All() // 根據 code 查詢 err, ok := catalog.Get("E1001") // 根據分類查詢 authErrors := catalog.ByCategory("auth")
AppError 的 With*() 方法永遠回傳副本,原始定義不會被修改:
original := errors.Define("E1", 404, "Not found", "general") copy1 := original.With("id", 1) copy2 := original.With("id", 2) // original.Details == nil(未被修改) // copy1.Details == {"id": 1} // copy2.Details == {"id": 2}
| Code | HTTP | Message | Category |
|---|---|---|---|
| E0001 | 404 | Resource not found | general |
| E0002 | 400 | Bad request | general |
| E0003 | 500 | Internal server error | general |
| E0004 | 405 | Method not allowed | general |
| E1001 | 422 | Validation failed | validation |
| E1002 | 400 | Missing required field | validation |
| E1003 | 400 | Invalid format | validation |
| E2001 | 401 | Authentication required | auth |
| E2002 | 403 | Permission denied | auth |
| E2003 | 401 | Token expired | auth |
pkg/errors/
├── catalog.go AppError、Define()、Catalog、預定義錯誤
├── context.go AbortWithAppError()、RespondError()
└── catalog_test.go 19 個單元測試
設計文件
套件
- config — 設定
- context — 請求上下文
- router — 路由器
- server — 伺服器
- middleware — 中介層
- websocket — WebSocket
- hidb — 資料庫 ORM
- hidb/cassandra — Cassandra
- logger — 日誌
- json — JSON 處理
- grpc — gRPC
AI 協作工具鏈
- schema — Schema-first 路由
- manifest — 專案 Manifest
- contract — Contract Testing
- errors — Typed Error Catalog
- migrate — Migration Diff
- scaffold — 智慧 Scaffold
- airules — AI Rules
CLI 命令
- hyp 總覽
- hyp new
- hyp api
- hyp run
- hyp restart
- hyp generate
- hyp migrate
- hyp context
- hyp ai-rules
- hyp chkcomment
- hyp impact
- hyp docker
- hyp health
- hyp version
- hyp difflog
Design Docs
Packages
- config — Configuration
- context — Request Context
- router — Router
- server — Server
- middleware — Middleware
- websocket — WebSocket
- hidb — Database ORM
- hidb/cassandra - Cassandra 5.0
- logger — Logger
- json — JSON
- grpc — gRPC
AI Collaboration Toolchain
- schema — Schema-first Routing
- manifest — Project Manifest
- contract — Contract Testing
- errors — Typed Error Catalog
- migrate — Migration Diff
- scaffold — Smart Scaffold
- airules — AI Rules
CLI Commands