go-error
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGo Error
Go 错误
Generate typed custom errors for module-level packages.
errs为模块级 包生成类型化自定义错误。
errsWhen to Use
适用场景
- Add new custom typed error definitions to a module
- Extend existing errs.go with new error codes
- Create validation error helpers with field-level details
- 为模块添加新的自定义类型错误定义
- 用新的错误码扩展现有 errs.go 文件
- 创建携带字段级别详情的校验错误辅助函数
Pattern
规范模式
Place errors in:
internal/modules/<module>/errs/errs.goEach module error file follows:
package errs- Imports:
net/httpbrickserrs "github.com/cristiano-pacheco/bricks/pkg/errs"
- block with exported error variables
var (...) - Error creation via:
brickserrs.New("<MODULE>_<NN>", "<message>", http.<Status>, nil)
- Optional helper constructors for validation errors that carry field-level details
错误定义存放路径:
internal/modules/<module>/errs/errs.go每个模块的错误文件遵循以下规则:
package errs- 导入依赖:
net/httpbrickserrs "github.com/cristiano-pacheco/bricks/pkg/errs"
- 在 代码块中定义导出的错误变量
var (...) - 错误创建方式:
brickserrs.New("<MODULE>_<NN>", "<message>", http.<Status>, nil)
- 可选:为携带字段级别详情的校验错误添加辅助构造函数
Example Structure
结构示例
go
package errs
import (
"net/http"
brickserrs "github.com/cristiano-pacheco/bricks/pkg/errs"
)
var (
// ErrProfileValidationFailed is returned when profile validation fails.
ErrProfileValidationFailed = brickserrs.New(
"PROFILE_01",
"profile validation failed",
http.StatusBadRequest,
nil,
)
// ErrProfileNotFound is returned when the profile is not found.
ErrProfileNotFound = brickserrs.New("PROFILE_02", "profile not found", http.StatusNotFound, nil)
)
// NewProfileValidationError returns a structured validation error with field-level details.
func NewProfileValidationError(details []brickserrs.Detail) *brickserrs.Error {
return brickserrs.New(
ErrProfileValidationFailed.Code,
ErrProfileValidationFailed.Message,
ErrProfileValidationFailed.Status,
details,
)
}go
package errs
import (
"net/http"
brickserrs "github.com/cristiano-pacheco/bricks/pkg/errs"
)
var (
// ErrProfileValidationFailed is returned when profile validation fails.
ErrProfileValidationFailed = brickserrs.New(
"PROFILE_01",
"profile validation failed",
http.StatusBadRequest,
nil,
)
// ErrProfileNotFound is returned when the profile is not found.
ErrProfileNotFound = brickserrs.New("PROFILE_02", "profile not found", http.StatusNotFound, nil)
)
// NewProfileValidationError returns a structured validation error with field-level details.
func NewProfileValidationError(details []brickserrs.Detail) *brickserrs.Error {
return brickserrs.New(
ErrProfileValidationFailed.Code,
ErrProfileValidationFailed.Message,
ErrProfileValidationFailed.Status,
details,
)
}Generation Steps
生成步骤
-
Identify error details:
- Target module (e.g., ,
catalog,profile,ai)export - Error variable name ()
ErrProfileNotFound - Lowercase message ()
"profile not found" - HTTP status ()
http.StatusNotFound
- Target module (e.g.,
-
Find the next code:
- Open
internal/modules/<module>/errs/errs.go - Extract existing codes for that module prefix
- Allocate the next available sequential code:
- Single digits are zero-padded: ,
CATALOG_01, ...,CATALOG_02CATALOG_09 - Double digits are not padded: ,
CATALOG_10, ...CATALOG_11
- Single digits are zero-padded:
- Keep code uniqueness inside the module
- Open
-
Add the new error:
- Insert into the module block
var (...) - Keep domain-group ordering used by the file
- Add a short doc comment when comments are already present in the file
- Insert into the module
-
Add a helper constructor if needed:
- When the error is a validation error that carries field-level details, add a function
NewXxxValidationError(details []brickserrs.Detail) *brickserrs.Error - Reuse the pre-defined variable's ,
.Code, and.Messagefields.Status
- When the error is a validation error that carries field-level details, add a
-
Validate usage path:
- Ensure new/updated usecases, validators, handlers, or enum constructors return the new typed error
- Do not return raw from business flows when a typed module error exists
errors.New(...)
-
Update translations (mandatory):
- Every new custom error must add a translation entry in under the
locales/en.jsonkey"errors" - Use the error code as key and a properly capitalized, user-facing sentence as value:
"PROFILE_02": "Profile not found" - If additional locale files exist (for example ), add the same key there too
locales/pt_BR.json - Keep translation keys and structure consistent across all locale files
- Do not merge a new custom error without the corresponding locale updates
- Every new custom error must add a translation entry in
-
确定错误详情:
- 目标模块(例如 、
catalog、profile、ai)export - 错误变量名()
ErrProfileNotFound - 小写错误消息()
"profile not found" - HTTP 状态码()
http.StatusNotFound
- 目标模块(例如
-
查找下一个可用错误码:
- 打开
internal/modules/<module>/errs/errs.go - 提取该模块前缀下已有的错误码
- 分配下一个可用的顺序码:
- 个位数补零:、
CATALOG_01、...、CATALOG_02CATALOG_09 - 两位数无需补零:、
CATALOG_10、...CATALOG_11
- 个位数补零:
- 保证模块内错误码唯一
- 打开
-
添加新错误:
- 插入到模块的 代码块中
var (...) - 遵循文件已有的领域分组排序规则
- 如果文件中已有注释,为新错误添加简短的文档注释
- 插入到模块的
-
按需添加辅助构造函数:
- 如果错误是携带字段级别详情的校验错误,添加 函数
NewXxxValidationError(details []brickserrs.Detail) *brickserrs.Error - 复用预定义变量的 、
.Code和.Message字段.Status
- 如果错误是携带字段级别详情的校验错误,添加
-
校验使用路径:
- 确保新增/更新的用例、校验器、处理器或枚举构造函数返回新的类型化错误
- 当存在对应的模块类型化错误时,业务流程中不要返回原始的
errors.New(...)
-
更新翻译(强制要求):
- 每个新增的自定义错误都必须在 的
locales/en.json键下添加翻译条目"errors" - 使用错误码作为键,首字母大写的面向用户的语句作为值:
"PROFILE_02": "Profile not found" - 如果存在其他语言的本地化文件(例如 ),也要在其中添加相同的键
locales/pt_BR.json - 保持所有本地化文件中的翻译键和结构一致
- 没有完成对应本地化更新的自定义错误不要合并
- 每个新增的自定义错误都必须在
Naming Conventions
命名规范
- Variable: + clear domain phrase in PascalCase
Err- Example: ,
ErrProfileNotFoundErrAIGenerationFailed
- Example:
- Code:
<MODULE>_<NN>- ,
CATALOG_09,EXPORT_15AI_07 - Always at least 2 digits; single digits are zero-padded
- Message:
- All lowercase in — the locale file (
brickserrs.New()) provides the user-facing capitalized formlocales/en.json - Short and specific, no trailing punctuation
- Examples: ,
"profile not found","invalid prompt type""ai provider unavailable"
- All lowercase in
- HTTP status:
- Validation errors:
http.StatusBadRequest - Auth failures: /
http.StatusUnauthorizedhttp.StatusForbidden - Missing resources:
http.StatusNotFound - Conflicts:
http.StatusConflict - Rate limit:
http.StatusTooManyRequests - Upstream/AI failures:
http.StatusBadGateway - Capacity/availability:
http.StatusServiceUnavailable - Infra/internal failures:
http.StatusInternalServerError
- Validation errors:
- 变量名:+ 帕斯卡命名的清晰领域短语
Err- 示例:、
ErrProfileNotFoundErrAIGenerationFailed
- 示例:
- 错误码:
<MODULE>_<NN>- 示例:、
CATALOG_09、EXPORT_15AI_07 - 始终至少2位数字;个位数补零
- 示例:
- 错误消息:
- 中的消息全部小写——本地化文件(
brickserrs.New())提供面向用户的首字母大写格式locales/en.json - 简短明确,末尾无标点
- 示例:、
"profile not found"、"invalid prompt type""ai provider unavailable"
- HTTP 状态码:
- 校验错误:
http.StatusBadRequest - 认证失败:/
http.StatusUnauthorizedhttp.StatusForbidden - 资源不存在:
http.StatusNotFound - 资源冲突:
http.StatusConflict - 限流:
http.StatusTooManyRequests - 上游/AI 服务故障:
http.StatusBadGateway - 容量/可用性问题:
http.StatusServiceUnavailable - 基础设施/内部故障:
http.StatusInternalServerError
- 校验错误:
Implementation Checklist
实现检查清单
- Open target
internal/modules/<module>/errs/errs.go - Compute next unique module code (zero-padded 2-digit format)
- Add exported variable with
Err...brickserrs.New(...) - Use all-lowercase message string
- Match existing domain-group ordering style
- Ensure message and status align with domain behavior
- Add helper if it is a validation error
NewXxxValidationError(details []brickserrs.Detail) - Replace raw error returns in calling code with typed where applicable
errs.Err... - Add translation for the new error in under
locales/en.jsonwith proper sentence-case value"errors" - Add the same translation key in every other existing locale file (e.g., )
locales/pt_BR.json - Run to catch style and static analysis issues
make lint - Run to ensure no nil pointer dereferences are introduced
make nilaway
- 打开目标路径的
internal/modules/<module>/errs/errs.go - 计算下一个唯一的模块错误码(补零的2位格式)
- 通过 添加导出的
brickserrs.New(...)变量Err... - 使用全小写的消息字符串
- 符合已有的领域分组排序风格
- 确保消息和状态码与领域行为匹配
- 如果是校验错误,添加 辅助函数
NewXxxValidationError(details []brickserrs.Detail) - 在适用的调用代码中,将原始错误返回替换为类型化的
errs.Err... - 在 的
locales/en.json下添加新错误的翻译,值使用正确的句首大写格式"errors" - 在所有其他已有的本地化文件(例如 )中添加相同的翻译键
locales/pt_BR.json - 运行 检查风格和静态分析问题
make lint - 运行 确保没有引入空指针引用问题
make nilaway
Usage Pattern
使用示例
go
if input.Phone == "" {
return errs.ErrPhoneNumberRequired
}
if profile == nil {
return errs.ErrProfileNotFound
}go
if input.Phone == "" {
return errs.ErrPhoneNumberRequired
}
if profile == nil {
return errs.ErrProfileNotFound
}Critical Rules
核心规则
- No standalone functions: When a file contains a struct with methods, do not add standalone functions. Use private methods on the struct instead.
- Do not create a new error package; use module-local
internal/modules/<module>/errs - Do not duplicate codes within the same module
- Do not return persistence or infrastructure-specific raw errors to transport when a typed domain error exists
- Keep error messages stable once exposed, unless migration/compatibility impact is accepted
- Every new custom error requires locale entries in and all other existing locale files
locales/en.json - Messages in are always lowercase; user-facing capitalization lives in the locale file
brickserrs.New()
- 禁止独立函数:如果文件中包含带有方法的结构体,不要添加独立函数,改用结构体的私有方法
- 不要创建新的错误包,使用模块本地的
internal/modules/<module>/errs - 同一模块内不要重复定义错误码
- 当存在对应的领域类型化错误时,不要将持久层或基础设施相关的原始错误返回给传输层
- 错误消息一旦对外暴露后要保持稳定,除非接受迁移/兼容性影响
- 每个新增的自定义错误都需要在 和所有其他已有的本地化文件中添加本地化条目
locales/en.json - 中的消息始终使用小写;面向用户的大写格式存放在本地化文件中
brickserrs.New()