编码为JSON时,Golang错误类型为空

put*_*tab 9 json struct go

我正在尝试为REST API编码一些JSON,除了一些错误之外,一切正常.例如,使用此结构:

type TemplateResponse struct {
    Message string
    Error   error
    Template Template
}
Run Code Online (Sandbox Code Playgroud)

编码此数据:

res := TemplateResponse{"Template not found.", fmt.Errorf("There is no template on this host with the name " + vars["name"]), Template{}}
json.NewEncoder(w).Encode(res)
Run Code Online (Sandbox Code Playgroud)

返回:

{
  "Message": "Template not found.",
  "Error": {},
  "Template": {
    "Name": "",
    "Disabled": false,
    "Path": "",
    "Version": ""
  }
}
Run Code Online (Sandbox Code Playgroud)

我在应用程序中看起来似乎是随机的,其中'error'类型被返回为空.有任何想法吗?

谢谢!

icz*_*cza 12

因为error只是一个界面.它可以包含实现它的任何具体类型的值.

在您的示例中,您曾fmt.Errorf()用于创建error值.该调用errors.New()返回指向未导出errors.errorString结构的值的指针.它的定义是:

type errorString struct {
    s string
}
Run Code Online (Sandbox Code Playgroud)

这个结构值将被封送,但由于它没有导出的字段(只有导出的字段被编组),它将是一个空的JSON对象:{}.

"修复"是:不要编组"通用"接口的值,依赖于动态值可以有意义地编组到JSON中.相反,您应该添加一个存储错误字符串(结果error.Error())的Error error字段,并省略编组中的字段,例如:

type TemplateResponse struct {
    Message  string
    Error    error `json:"-"`
    ErrorMsg string
    Template Template
}
Run Code Online (Sandbox Code Playgroud)

当然,您还需要ErrorMsg在编组之前设置/填充该字段.

或者,如果您不需要将error值存储在结构中,请完全删除该字段:

type TemplateResponse struct {
    Message  string
    ErrorMsg string
    Template Template
}
Run Code Online (Sandbox Code Playgroud)

如果你仍想保留的Error error字段(而不是ErrorMsg字段),那么你需要通过执行来实现自定义编组逻辑json.Marshaler接口,您可以在"转化" error值有意义的string,例如(或成可以编组另一个值正确).