
在 go 构建 json api 时,需将错误以标准 json 格式(如 {"error": "message"})返回;直接嵌入 error 字段无法自动序列化,须显式实现 json.marshaler 接口。
要让自定义错误类型(如 JsonErr)在调用 json.Marshal 或 json.NewEncoder.Encode 时输出结构化的 JSON 错误响应,关键在于正确实现 json.Marshaler 接口,而非依赖 error 接口本身——因为 encoding/json 包不会对 error 类型做特殊处理,且大多数 error 实现(如 errors.New 返回的 *errors.errorString)内部字段非导出,反射无法访问。
推荐做法是采用内嵌 error 接口 + 自定义 MarshalJSON() 方法的方式,简洁且符合 Go 惯例:
type JsonErr struct {
error // 内嵌 error,自动获得 Error() 方法
}
func (e JsonErr) MarshalJSON() ([]byte, error) {
// 安全转义错误消息,避免 JSON 注入(生产环境务必使用)
msg := strings.ReplaceAll(e.Error(), `"`, `\"`)
return []byte(`{"error": "` + msg + `"}`), nil
}⚠️ 注意:上述字符串拼接仅作演示,实际项目中应使用 json.Marshal 处理消息字段以确保 JSON 安全性:
使用模板与程序分离的方式构建,依靠专门设计的数据库操作类实现数据库存取,具有专有错误处理模块,通过 Email 实时报告数据库错误,除具有满足购物需要的全部功能外,成新商城购物系统还对购物系统体系做了丰富的扩展,全新设计的搜索功能,自定义成新商城购物系统代码功能代码已经全面优化,杜绝SQL注入漏洞前台测试用户名:admin密码:admin888后台管理员名:admin密码:admin888
func (e JsonErr) MarshalJSON() ([]byte, error) {
type Alias JsonErr // 防止无限递归(避免再次调用本方法)
return json.Marshal(struct {
Error string `json:"error"`
}{
Error: e.Error(),
})
}这样既保持了类型清晰,又利用了标准库的转义与格式化能力。使用示例如下:
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(JsonErr{errors.New("Invalid request syntax")})
}
// 输出:{"error": "Invalid request syntax"}✅ 总结:
- 不要试图通过结构体标签(如 json:"error")直接 marshal error 字段——它会变成空对象 {};
- 必须实现 MarshalJSON() ([]byte, error);
- 优先使用 json.Marshal 序列化内部字段,而非手动拼接字符串;
- 可进一步扩展 JsonErr 支持状态码、详情字段等,只需在匿名结构体中添加对应字段即可。









