如何在Golang中捕获JSON序列化错误_Golangjson.Marshal错误处理示例


json.Marshal 从不 panic,只返回 error;真正导致崩溃的是忽略 error 后使用 nil 切片、空指针或类型断言失败,正确做法是立即检查并处理 error。

为什么 json.Marshal 会 panic?它其实不会

很多人以为 json.Marshal 可能 panic,实际它**从不 panic**,而是返回 error。真正让你程序崩溃的,往往是忽略这个 error 后继续用 nil 的字节切片(比如传给 HTTP 响应或写文件),或在后续逻辑中触发空指针/类型断言失败。

  • json.Marshal 只在遇到不可序列化值时返回非 nil 错误,例如含 funcchan、未导出字段且无 json tag、循环引用等
  • 错误类型是 *json.UnsupportedTypeError*json.InvalidUTF8Error 等,都实现了 error 接口,可直接判断
  • 不要用 recover() 拦截 json.Marshal —— 它根本不会抛出 panic

正确处理 json.Marshal 错误的惯用写法

Go 中标准做法是「检查 error,立刻处理」。常见错误是只打印日志却不终止流程,导致下游收到空数据或乱码。

data := struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
    Fn   func() `json:"-"` // 不导出 + 无 tag → 会出错
}{
    Name: "Alice",
    Age:  30,
}

b, err := json.Marshal(data)
if err != nil {
    // ✅ 正确:区分错误类型,做针对性响应
    switch e := err.(type) {
    case *json.UnsupportedTypeError:
        log.Printf("无法序列化字段 %s: %v", e.Type.String(), e.Error())
        http.Error(w, "响应数据构造失败", http.StatusInternalServerError)
        return
    case *json.InvalidUTF8Error:
        log.Printf("字符串含非法 UTF-8: %v", e)
        http.Error(w, "数据编码异常", http.StatusBadRequest)
        return
    default:
        log.Printf("JSON 序列化未知错误: %v", err)
        http.Error(w, "服务内部错误", http.StatusInternalServerError)
        return
    }
}
w.Header().Set("Content-Type", "application/json")
w.Write(b)

哪些值会导致 json.Marshal 返回 error?

不是所有 Go 类型都能直译成 JSON。以下情况必然失败,且错误信息明确:

  • 含有 funcchancomplex64/complex128 类型字段(即使已导出)
  • 结构体字段未导出(首字母小写)且没加 json:"..." tag;若加了 json:"-" 则跳过,不报错
  • map 的 key 类型不是 stringintint32 等基本可比较类型(如 map[struct{X int}]string
  • 字符串字段包含非法 UTF-8 字节(例如从二进制读取后未校验就赋值)
  • 嵌套结构体存在循环引用(A 包含 B,B 又包含 A 指针)—— 这会触发 json: unsupported value: encountered a cycle

测试和调试 json.Marshal 错误的实用技巧

线上环境难复现循环引用或非法 UTF-8,建议在单元测试中主动构造边界 case。

  • reflect.ValueOf(v).Kind() == reflect.Func 提前过滤掉含函数字段的结构体(适合封装自己的 SafeMarshal
  • 对用户输入的字符串,用 utf8.Valid([]byte(s)) 预检,避免传入 json.Marshal 后才报错
  • 开启 go test -v 并在测试中故意传入含 chan int 的结构体,确认错误分支被覆盖
  • 注意:json.Marshal(nil) 是合法的,返回字面量 null,不会出错

最常被忽略的是:错误处理后忘记 return,导致仍执行后续 w.Write(nil) —— 这会让客户端收到空响应而不报错,排查难度远大于直接返回 500。


# js  # json  # go  # golang  # 编码  # app  # 字节  # usb  # switch  # 为什么  # red  # String  # NULL  # 封装  # Error  # 字符串  # 结构体  # int  # 循环  # 指针  # 接口  # Struct  # 空指针  # 切片  # nil  # map  # kind  # http  # 的是  # 报错  # 序列化  # 这会  # 自己的  # 让你  # 都能  # 很多人  # 并在  # 而不 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: Win11怎么设置默认浏览器Chrome_Windows11修改默认网页打开方式  c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】  php增删改查需要哪些扩展_开启mysqli或pdo扩展方法【说明】  如何使用Golang table-driven基准测试_多组数据测量函数效率  Win10如何更改电脑休眠时间_Windows10电源和睡眠选项调整  全球各国上班时间表外贸邮件时间  如何使用Golang捕获并记录协程panic_保证主程序稳定运行  Win11怎么更改鼠标指针方案_Windows11自定义鼠标光标样式与大小  Go 中实现 Python urllib.quote() 等效功能的正确方式  如何使用Golang实现文件追加操作_向已有文件追加数据  Python对象生命周期管理_创建销毁说明【指导】  Python对象比较与排序_集合使用说明【指导】  c++20的std::format怎么用 比printf更安全高效的格式化方法【详解】  Win10系统怎么查看端口状态_Windows10 CMD查看网络连接  Win11怎么清理C盘OneDrive缓存_Win11清理OneDrive缓存技巧【方法】  Win11如何关闭游戏模式 Win11禁用Xbox Game Bar录制【优化】  如何在Golang中使用log包输出不同级别日志_Golang log日志管理与分类  php订单日志怎么记录评价_php记录订单评价日志方法【方法】  windows如何修改文件默认打开方式_windows设置程序关联教程  Linux怎么禁止Root用户远程登录_Linux系统SSH加固与安全设置【教程】  c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】  Win11如何更改用户账户文件夹名称 Win11修改C:Users用户名【终极教程】  Win11怎么设置ipv4地址_Windows 11固定静态IP地址配置教程【详解】  php订单日志怎么在swoole写_php协程swoole写订单日志教程【教程】  Windows10电脑怎么设置文件权限_Win10安全选项卡所有者修改  Win11时间不对怎么同步_Win11自动校准互联网时间【设置】  如何使用Golang处理静态文件缓存_提高页面加载速度  如何优化Golang Web性能_Golang HTTP服务器性能提升方法  Python并发安全问题_资源竞争说明【指导】  C#如何在一个XML文件中查找并替换文本内容  c# 如何深拷贝和浅拷贝  Win11怎样安装网易云音乐_Win11安装网易云教程【步骤】  Win11文件扩展名怎么显示_Win11查看文件后缀名设置【基础】  网站体验不好=浪费钱:如何提升-用户体验效果差  Win11如何设置自动关机 Win11定时关机命令使用教程【技巧】  LINUX的SELinux是什么_详解LINUX强制访问控制系统的入门与配置  Win11怎么关闭系统提示音_Windows11声音方案设为无声教程  如何使用正则表达式批量替换重复的 *- 模式为固定字符串  Python邮件系统自动化教程_批量发送解析与模板应用  如何快速验证Golang安装是否成功_运行go version和hello world示例  如何在Golang中实现RPC异步返回_Golang RPC异步处理与回调方法  Win10如何更改网络连接_Windows10以太网属性IP配置  如何在Golang中写入XML文件_生成符合规范的XML数据  windows如何禁用驱动程序强制签名_windows高级启动设置指南  c++如何使用std::bind绑定函数参数_c++ 占位符std::placeholders使用【详解】  c# 在ASP.NET Core中管理和取消后台任务  Drupal 中 HTML 链接被双重转义导致渲染异常的解决方案  php删除数据怎么软删除_添加is_del字段标记删除【技巧】  Python 中将 ISO 8601 时间戳转换为日期并计算日期差值的完整教程  Windows10如何更改日期格式_Win10区域设置短日期修改 

 2026-01-01

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.