0

0

Golang公共API返回错误的规范建议

P粉602998670

P粉602998670

发布时间:2026-01-12 16:09:26

|

296人浏览过

|

来源于php中文网

原创

应统一错误响应结构为含code、message、request_id的APIError,禁用http.Error;通过中间件+context透传request_id;panic时recover并走统一错误流程,同时校验ctx.Err()防止二次panic。

golang公共api返回错误的规范建议

Go HTTP handler 中如何统一返回错误结构

直接用 http.Error 或裸写 JSON 会导致前端难解析、日志难聚合、错误码不一致。建议所有公共 API 的错误响应都走同一结构体,且必须包含 code(业务码)、message(用户提示)、request_id(用于排查)。

常见错误是把 error 值直接序列化进 JSON,结果出现 "error": "EOF" 这类不可读内容;或漏掉 Content-Type: application/json 导致前端解析失败。

  • 定义统一错误响应结构,例如:
    type APIError struct {
    	Code      int    `json:"code"`
    	Message   string `json:"message"`
    	RequestID string `json:"request_id,omitempty"`
    }
  • 在中间件或封装的 WriteJSON 方法中统一处理:遇到 error 类型时,自动转成 APIError 并设状态码(如 400 对应参数错误,500 对应未预期错误)
  • 禁止在 handler 里调用 http.Error;它不支持自定义字段,且默认 Content-Type 是 text/plain

区分 error 类型:业务错误 vs 系统错误 vs 验证错误

前端需要根据 code 做不同动作(比如重试、跳登录页、弹提示),所以不能全塞 500 或只用 errors.New 包裹字符串。

推荐用带类型标签的错误,比如用 fmt.Errorf("invalid token: %w", err) + 自定义错误类型实现 IsUnwrap,再在响应层映射到对应 code

立即学习go语言免费学习笔记(深入)”;

  • ErrValidationcode: 400(参数校验失败)
  • ErrUnauthorizedcode: 401(token 过期/无效)
  • ErrNotFoundcode: 404(资源不存在)
  • ErrInternalcode: 500(服务端 panic 或 DB 超时等)

避免把数据库错误(如 "pq: duplicate key violates unique constraint")直接透出给前端——这类信息要被拦截并转为更友好的 message,同时记录完整原始 error 到日志。

Pixso
Pixso

Pixso一站式完成原型、设计、交互与交付,为数字化团队协作提效。

下载

request_id 怎么生成和透传

没有 request_id,线上报错时根本没法对齐日志。它必须在入口(如 http.ServeHTTP 第一行)就生成,并贯穿整个请求生命周期。

  • uuid.NewString()rand.String(12) 生成,不要用时间戳或递增 ID(并发不安全、易猜测)
  • 存入 context.Context,后续所有日志、DB 查询、下游调用都要带上它
  • 响应头里加 X-Request-ID,响应体 JSON 里也放一份 request_id 字段,方便前端上报问题时提供上下文
  • 如果用了 Gin/Echo,别依赖框架默认的 X-Request-ID 中间件——确认它是否真会写入响应体;很多只写 header 不写 body

panic 后如何安全 fallback 到错误响应

Go HTTP server 遇到 panic 默认会返回 500 Internal Server Error 和空 body,前端收不到 coderequest_id,监控也抓不到上下文。

必须用 recover() 拦住 panic,并强制走统一错误响应流程:

  • 在最外层 middleware 里 defer recover,捕获后调用统一错误写入函数
  • 恢复后仍要打印 stacktrace 到日志(用 debug.PrintStack()runtime/debug.Stack()),但绝不返回给前端
  • 注意:recover 只对当前 goroutine 有效;如果业务启了新 goroutine(如 go fn()),需各自加 recover

最容易被忽略的是 context 超时或取消后继续写响应——recover 之后还得检查 ctx.Err() != nil,否则可能 panic 恢复了,但连接已断,再写 JSON 会 panic 二次。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

178

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

226

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

337

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

208

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

189

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

192

2025.06.17

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

10

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.2万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号