Skip to content

错误消息

govalid 的错误系统设计目标是:开箱可用,且覆盖也足够简单。每条 失败的规则会产生一个 *ErrContext,其 Error() 返回由三部分组成 的可读字符串:

  1. 字段的 label(如 "邮箱"
  2. 规则的 模板(如 "不能为空"
  3. 规则的 限制值(如果有的话,例如 max:100100

例如: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>" 这类跨模板残留绝不会发生。

基于 MIT 协议发布。