gogin ErrorMiddleware的使用错误 go gin func ErrorMiddleware() gin.HandlerFunc { return func(c *gin.Context) { defer func() { if err : recover(); err ! nil { c.IndentedJSON(http.StatusOK, basedto.ResultError(err.(error))) c.Abort() } }() // 处理业务错误 if len(c.Errors) 0 { // 你可以在这里定义你的错误处理逻辑 golog.Error(jsonutils.ToJsonPretty(c.Errors)) c.JSON(http.StatusInternalServerError, gin.H{message: Internal Server Error}) c.Abort() // 终止请求 } c.Next() } }代码有没有问题这段代码有严重问题核心在于c.Errors的检查时机完全错误。以下是逐条分析❌ 核心问题1.c.Errors检查在c.Next()之前 → 永远为空go// 此时后续 Handler 还没执行c.Errors 永远是空的 if len(c.Errors) 0 { ... } c.Next() // 后续 Handler 在这里才执行修复必须放到c.Next()之后。2.recover()中的类型断言可能二次 Panicgoerr.(error) // 如果 recover 到的不是 error比如字符串 panic(xxx)这里会再 panic虽然 recover 里再 panic 会被 Go 运行时吞掉但不够安全。3. 响应写入时机问题如果 panic 发生在某个 Handler 已经调用了c.JSON()之后recover 中再次调用c.IndentedJSON会导致http: superfluous response.WriteHeader call警告。✅ 修复后的代码gofunc ErrorMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // 1. 先注册 defer recover必须在最前面 defer func() { if r : recover(); r ! nil { // 安全地处理任意类型 var errMsg string switch e : r.(type) { case error: errMsg e.Error() case string: errMsg e default: errMsg fmt.Sprintf(unknown panic: %v, r) } golog.Error(panic recovered: , errMsg) // 避免重复写入 if !c.Writer.Written() { c.IndentedJSON(http.StatusOK, basedto.ResultError(errors.New(errMsg))) } c.Abort() } }() // 2. 执行后续 Handler c.Next() // 3. 在 c.Next() 之后检查业务错误 if len(c.Errors) 0 { golog.Error(jsonutils.ToJsonPretty(c.Errors)) // 取最后一个错误或合并所有错误 lastErr : c.Errors.Last() if !c.Writer.Written() { c.JSON(http.StatusInternalServerError, gin.H{ message: lastErr.Error(), }) } // c.Next() 已经执行完这里不需要 Abort() } } } 关键差异对照表格问题你的代码修复后c.Errors检查时机c.Next()之前永远空c.Next()之后recover 类型断言err.(error)可能二次 panicswitch安全处理任意类型重复写入风险无保护c.Writer.Written()判断Abort()位置c.Next()前会阻止执行只在 recover 中使用 额外建议如果你的业务代码是通过c.Error(err)收集错误而非直接c.JSON返回建议统一错误码go// 业务 Handler 中 if err ! nil { c.Error(err) // 不直接返回交给中间件统一处理 return // 终止当前 Handler但继续走中间件 }如果你已经在 Handler 里直接c.JSON返回错误了那c.Errors机制就用不上这个中间件里的c.Errors分支可以删掉只保留 recover 即可。需要我帮你改成只处理 panic 的精简版本吗

相关新闻

最新新闻

澳洲NAATI翻译渠道测评:3大正规渠道实测,办理证件翻译不踩坑

澳洲NAATI翻译渠道测评:3大正规渠道实测,办理证件翻译不踩坑

正规澳洲NAATI翻译件,会完整还原各类澳洲证件、文书的全部信息,搭配认证译员签章、资质编码及翻译声明,是具备有效核验效力的正式文件,个人手动翻译、无资质翻译均无法通过合规核验。下文实测澳洲NAATI翻译三大办理渠道&#xff0…

2026/7/31 18:48:15
CS231N_17_KOR_SUB项目贡献指南:如何参与韩语字幕的改进与完善

CS231N_17_KOR_SUB项目贡献指南:如何参与韩语字幕的改进与完善

CS231N_17_KOR_SUB项目贡献指南:如何参与韩语字幕的改进与完善 【免费下载链接】CS231N_17_KOR_SUB CS231N 2017 video subtitles translation project for Korean Computer Science students 项目地址: https://gitcode.com/gh_mirrors/cs/CS231N_17_KOR_SUB …

2026/7/31 18:48:15
2026登报遗失声明线上办理方法测评:选对渠道,顺利登报

2026登报遗失声明线上办理方法测评:选对渠道,顺利登报

丢失营业执照、公章、身份证、资格证书等证件后,政务补办、工商备案均要求出具正规登报遗失声明。目前登报业务已支持线上办理,但很多人不了解标准操作流程,难以分辨各平台的合规性、时效及收费差异,容易出现登报无效、延误补办等…

2026/7/31 18:48:15
2026登报声明办理流程+渠道实测测评!流程、材料、费用对比

2026登报声明办理流程+渠道实测测评!流程、材料、费用对比

办理材料:个人业务需准备姓名、证件编号、联系电话;企业业务需准备公司全称、统一社会信用代码、遗失/公示相关信息、联系人及电话。 测评渠道:慧办好线上小程序、其他线上登报服务平台、线下实体报社网点。 通用办理流程:整理公…

2026/7/31 18:48:15
银河麒麟软件包版本回退实操:yum downgrade避免升级翻车

银河麒麟软件包版本回退实操:yum downgrade避免升级翻车

麒麟系统回退软件包版本 RPM管理 RPM版本管理机制 RPM参数详解表 变更管理流程 单个软件包回退案例 准备好旧版本的软件包 查看现在版本 回退软件包版本 再次查看软件包版本 多个软件包回退 批量回退脚本 yum历史回退 本次记录rpm回退软件包版本 RPM管理 RPM版本管理机制 #mer…

2026/7/31 18:48:15
运维实战分享|VMware NSX 4.2.4.0 全套官方镜像资源实操指南

运维实战分享|VMware NSX 4.2.4.0 全套官方镜像资源实操指南

最近不少做私有云、数据中心网络运维的同行私信我,问哪里能找到完整、无删减的 NSX 官方全套镜像。很多朋友反馈官方下载门槛高、分卷文件零散,不同小版本还存在兼容性差异,部署、升级时经常踩版本不匹配、硬件不兼容的坑。 我也从事过企业机…

2026/7/31 18:43:15

月新闻