Gin 默认不捕获 panic 是错误认知;实际默认启用 Recovery() 中间件自动 recover panic 并返回 500,但仅记录日志、不对接 Sentry——必须手动在 defer recover 后调用 sentry.CaptureException() 或使用 sentrygin.New() 替代原生 Recovery() 才能上报。

为什么 Gin 默认不捕获 panic?
Gin 的 Recovery() 中间件会 recover panic 并返回 500,但默认不向 Sentry 上报——它只是吞掉 panic 后继续响应,Sentry 完全无感知。你得手动把 panic 捕获后交给 Sentry 处理,否则线上崩溃等于“静默失败”。
- 别依赖
Recovery()自动上报,它和 Sentry 无关 - 必须在
Recovery()之前或内部调用sentry.CaptureException() - 若用了自定义 error handler(比如
c.Error()),也要主动调用sentry.CaptureException(),否则业务层panic或errors.New()都不会进 Sentry
如何替换 Gin 默认 Recovery 中间件?
直接用 sentrygin.New() 替代原生 Recovery() 是最稳妥的方式,它会在 recover 后自动调用 sentry.CaptureException(),并带上 request、user、tags 等上下文。
- 初始化时调用
sentry.Init(),传入 DSN 和环境配置(如Environment: "production") - 注册中间件:
r.Use(sentrygin.New(sentrygin.Options{})),注意它必须放在Recovery()之前(否则被原生中间件截断) - 该中间件默认只捕获 panic,不捕获
c.Error()报错;如需上报业务错误,仍需手动调用sentry.CaptureException()
怎么给 Sentry 添加请求上下文(如 user、tags)?
Sentry 默认只记录 panic 堆栈,没有用户 ID、路径参数、trace ID 这些关键信息,排查时基本靠猜。必须在中间件里显式设置 scope。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 用
sentry.WithScope()包裹 handler,或在中间件中调用sentry.ConfigureScope() - 常见字段:
sentry.SetUser(sentry.User{ID: c.GetString("user_id")})、sentry.SetTag("path", c.Request.URL.Path) - 避免在全局 scope 设置,否则不同请求间数据污染;务必在每个请求的 scope 内设置
- 如果用了 OpenTracing,可从 context 提取 trace ID:
sentry.SetTag("trace_id", traceID)
为什么本地开发看不到 Sentry 错误?
不是代码没跑,而是 sentry.Init() 默认跳过 development 环境——这是 Sentry SDK 的硬编码行为,和你传的 Environment 配置无关。
立即学习“go语言免费学习笔记(深入)”;
- 开发时加
IgnoreErrors: []string{}并显式设Environment: "development"不起作用 - 真正生效的是
BeforeSend回调:返回nil就丢弃事件,返回 event 才上报;开发时可在此处放行 - 更简单做法:启动时检查
os.Getenv("GIN_MODE") == "debug",若为真则跳过sentry.Init(),或改用sentry.Flush()测试连通性
Scope 设置时机、环境判断逻辑、panic 捕获链路断点——这三处任一出错,Sentry 就成摆设。上线前用 panic("test") 验证端到端是否真能收到事件,别只看日志有没有打印。

















