错误消息
govalid 的错误系统设计目标是:开箱可用,且覆盖也足够简单。每条 失败的规则会产生一个 *ErrContext,其 Error() 返回由三部分组成 的可读字符串:
- 字段的 label(如
"邮箱") - 规则的 模板(如
"不能为空") - 规则的 限制值(如果有的话,例如
max:100的100)
例如:label 为 "评分",规则 min:0 产生 "评分应大于0"。
字段级覆盖:msg
最简单的方法是用结构体字段上的 msg 标签。第一条失败的规则会短路 到该文本:
go
type Form struct {
Password string `valid:"required;minlen:8;maxlen:64" label:"密码" msg:"密码长度需在 8-64 之间"`
}当文案比错因细节更重要时使用 msg。
替换规则模板
SetMessageTemplates 把你的覆盖项合并到某个 locale 的模板集合中。 默认 locale 是中文;传入 language.Tag 来更新其他 locale:
go
govalid.SetMessageTemplates(map[string]string{
"required": "can not be null",
"min": "must be greater than",
})
govalid.SetMessageTemplates(map[string]string{
"required": "must not be empty",
}, language.English)模板语法
模板可以携带占位符,或被 {{ … }} 包裹:
| 模式 | 效果 |
|---|---|
普通字符串(如 "不能为空") | 前置字段 label,限制值非 nil 时追加在尾部 |
包含 {field} / {limit} | 占位符按字面替换 |
被 {{ … }} 包裹 | 完全跳过 label 前缀和限制值后缀 |
go
govalid.SetMessageTemplates(map[string]string{
"min": "{{字段 {field} 必须 ≥ {limit}}}",
})
// → "字段 Score 必须 ≥ 10" (无 label 前缀,无限制值后缀)占位符常量 FieldNamePlaceholder = "{field}" 和 FieldLimitPlaceholder = "{limit}" 已被导出,方便你在按配置构造 模板时引用。
诊断模板
govalid 在诊断场景下使用三个内部模板,它们都以 _ 开头:
| 键 | 何时使用 |
|---|---|
_checkerNotFound | 标签引用了未注册的校验器 |
_unknownErrorTemplate | 自定义校验器命中未映射的 key |
_paramError | 标签参数缺失或非法 |
_valueTypeError | 运行时类型不被该校验器支持 |
_fieldNotFound | 跨字段规则引用了不存在的字段 |
像普通规则一样覆盖它们:
go
govalid.SetMessageTemplates(map[string]string{
"_checkerNotFound": "未知的校验规则",
})程序化访问
返回的 errs 切片中每一项都是 *ErrContext,其公开字段可以被 访问:
go
errs, ok := govalid.Check(form)
if !ok {
for _, e := range errs {
log.Printf("[%s] label=%q value=%v -> %s",
e.FieldName, e.FieldLabel, e.FieldValue, e)
}
}事后修改错误
*ErrContext 提供两个 mutator,方便你在事后微调消息——通常用在 自定义校验器内部:
go
ctx := govalid.NewErrorContext(c)
ctx.SetTemplate("alphadash") // 完全切换到另一个模板
ctx.SetFieldLimitValue(42) // 用新的限制值重新渲染SetTemplate 会清除之前设置的限制值,所以 "name can not be empty<old limit>" 这类跨模板残留绝不会发生。