Golang错误信息中如何显示行号
Golang错误信息中如何显示行号 当我使用 validate.struct() 后,如果我的内容存在一些验证错误,该函数会返回这些 ValidationErrors。 是否有可能向用户显示该特定元素所在的行号? 我正在使用 yaml 文件来解析和验证内容。如果有任何可能性,请给出建议?
func main() {
fmt.Println("hello world")
}
1 回复
更多关于Golang错误信息中如何显示行号的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Golang中,当使用validate.Struct()进行验证时,可以通过自定义错误消息或扩展验证错误来包含行号信息。以下是一个示例,展示如何将YAML行号与验证错误关联:
package main
import (
"fmt"
"gopkg.in/yaml.v3"
"github.com/go-playground/validator/v10"
)
type Config struct {
Name string `yaml:"name" validate:"required"`
Email string `yaml:"email" validate:"email"`
Age int `yaml:"age" validate:"gte=18"`
}
type ValidationErrorWithLine struct {
Field string
Tag string
Value interface{}
Line int
Message string
}
func main() {
yamlContent := `
name: John
email: invalid-email
age: 16
`
var config Config
var node yaml.Node
// 解析YAML并保留节点信息
err := yaml.Unmarshal([]byte(yamlContent), &node)
if err != nil {
panic(err)
}
// 从根节点提取配置
err = node.Decode(&config)
if err != nil {
panic(err)
}
validate := validator.New()
err = validate.Struct(config)
if err != nil {
if validationErrors, ok := err.(validator.ValidationErrors); ok {
errorsWithLines := make([]ValidationErrorWithLine, 0)
// 遍历YAML节点查找字段位置
var findFieldLine func(*yaml.Node, string) int
findFieldLine = func(n *yaml.Node, fieldName string) int {
if n.Kind == yaml.MappingNode {
for i := 0; i < len(n.Content); i += 2 {
keyNode := n.Content[i]
if keyNode.Value == fieldName {
return keyNode.Line
}
}
}
return 0
}
// 为每个验证错误添加行号
for _, validationErr := range validationErrors {
fieldName := validationErr.Field()
line := findFieldLine(node.Content[0], fieldName)
errorsWithLines = append(errorsWithLines, ValidationErrorWithLine{
Field: fieldName,
Tag: validationErr.Tag(),
Value: validationErr.Value(),
Line: line,
Message: fmt.Sprintf("Field '%s' failed validation '%s' at line %d",
fieldName, validationErr.Tag(), line),
})
}
// 显示带行号的错误信息
for _, errWithLine := range errorsWithLines {
fmt.Printf("Error at line %d: %s\n", errWithLine.Line, errWithLine.Message)
}
}
}
}
如果需要更精确的行号跟踪,可以考虑使用自定义验证器:
type ConfigWithLine struct {
Name string `yaml:"name" validate:"required"`
Email string `yaml:"email" validate:"email"`
Age int `yaml:"age" validate:"gte=18"`
Lines map[string]int `yaml:"-"`
}
func validateWithLineNumbers(yamlContent string) {
var node yaml.Node
err := yaml.Unmarshal([]byte(yamlContent), &node)
if err != nil {
panic(err)
}
configWithLine := ConfigWithLine{
Lines: make(map[string]int),
}
// 提取字段和行号
if node.Content[0].Kind == yaml.MappingNode {
content := node.Content[0].Content
for i := 0; i < len(content); i += 2 {
keyNode := content[i]
valueNode := content[i+1]
switch keyNode.Value {
case "name":
valueNode.Decode(&configWithLine.Name)
configWithLine.Lines["Name"] = keyNode.Line
case "email":
valueNode.Decode(&configWithLine.Email)
configWithLine.Lines["Email"] = keyNode.Line
case "age":
valueNode.Decode(&configWithLine.Age)
configWithLine.Lines["Age"] = keyNode.Line
}
}
}
validate := validator.New()
err = validate.Struct(configWithLine)
if err != nil {
if validationErrors, ok := err.(validator.ValidationErrors); ok {
for _, validationErr := range validationErrors {
fieldName := validationErr.Field()
if line, exists := configWithLine.Lines[fieldName]; exists {
fmt.Printf("Validation error for field '%s' at line %d: %s\n",
fieldName, line, validationErr.Tag())
}
}
}
}
}
这些示例展示了如何将YAML解析的行号信息与验证错误关联,从而向用户显示具体的行号位置。

