我正在尝试为REST API编码一些JSON,除某些错误外,其他所有东西都工作正常。例如,使用此结构:
type TemplateResponse struct {
Message string
Error error
Template Template
}
用此数据编码:
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)
返回值:
{
"Message": "Template not found.",
"Error": {},
"Template": {
"Name": "",
"Disabled": false,
"Path": "",
"Version": ""
}
}
我在我的应用程序中似乎是随机得到的,其中“错误”类型返回为空。有任何想法吗?
谢谢!
最佳答案
因为 error
只是一个接口(interface)。它可以保存实现它的任何具体类型的值。
在您的示例中,您使用 fmt.Errorf()
创建了error
值。这将调用 errors.New()
,该返回的指针指向未导出的errors.errorString
结构的值。其定义是:
type errorString struct {
s string
}
该struct值将被封送,但由于它没有导出的字段(仅封送了已导出的字段),因此它将是一个空的JSON对象:
{}
。“解决方案”是:不要封送“通用”接口(interface)的值,这取决于可以将动态值有意义地编码到JSON中。相反,您应该添加一个存储错误字符串(
error.Error()
的结果)的字段,并从封送处理中忽略Error error
字段,例如:type TemplateResponse struct {
Message string
Error error `json:"-"`
ErrorMsg string
Template Template
}
当然,您还需要在封送处理之前设置/填充
ErrorMsg
字段。或者,如果您不需要将
error
值存储在结构中,请完全删除该字段:type TemplateResponse struct {
Message string
ErrorMsg string
Template Template
}
如果您仍想保留
Error error
字段(而不是ErrorMsg
字段),则需要通过实现 json.Marshaler
接口(interface)来实现自定义封送处理逻辑,在该接口(interface)中,您可以将error
值“转换”为有意义的string
,例如(或转换为另一个)可以正确封送的值)。