当前位置: 首页 > news >正文

Golang web 项目中实现自定义 recovery 中间件

为什么需要实现自定义 recovery 中间件?

在 Golang 的 Web 项目中,自定义 recovery 中间件是一种常见的做法,用于捕获并处理应用程序的运行时错误,以避免整个应用程序崩溃并返回对应格式的响应数据。

很多三方 web 框架(例如 gin、echo)都提供了官方实现的 recovery 中间件,但是官方实现的中间件并不一定能满足自己的需求。例如 gin 官方提供的 recovery 中间件,发生 panic 后会将当前请求的标准状态码置为 500,body 置为空。但是这样的返回数据与格式可能会和自己的项目要求不一致。例如,项目发生 panic 后是要求标准状态码依然返回 200,body 值为 {"code":-1, "data":nil,"msg":"xxx"},这种场景下,就需要实现自己的 recovery 中间件了。

如何实现自定义 recovery 中间件?

如果使用 gin 框架的话,就非常简单了,因为 gin 提供了完善的中间件功能,遵守 gin 的要求实现满足自己项目的功能就可以了,简单示例代码如下:

package mainimport ("github.com/gin-gonic/gin""log""net/http""runtime"
)func Recovery() gin.HandlerFunc {return func(c *gin.Context) {defer func() {if err := recover(); err != nil {const size = 64 << 10stack := make([]byte, size)stack = stack[:runtime.Stack(stack, false)]log.Printf("[GinPanic] %s\n", string(stack))c.JSON(http.StatusOK, struct {Code int         `json:"code"`Data interface{} `json:"data"`Msg  string      `json:"msg"`}{Code: -1,Data: nil,Msg:  "server panic",})c.Abort()}}()c.Next()}
}

使用示例如下:

package mainimport ("github.com/gin-gonic/gin""runtime"
)func main() {r := gin.New()r.Use(Recovery())r.GET("/test", func(c *gin.Context) {panic("Oops! Something went wrong.")})r.Run(":8080")
}

运行起来后,访问 /test 触发 panic 后返回了预期的结果,如下:

$ curl http://127.0.0.1:8080/test
{"code":-1,"data":null,"msg":"server panic"}

接下来再看一个基于原生包  net/http 的一个示例,代码如下:

package mainimport ("fmt""log""net/http""runtime/debug"
)// 自定义的recovery中间件
func recoveryMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {defer func() {if err := recover(); err != nil {// 打印错误信息log.Println("[Recovery] Panic:", err)// 打印堆栈跟踪信息log.Printf("[Recovery] Stack Trace:\n%s\n", debug.Stack())// 返回一个适当的错误响应给客户端fmt.Fprintf(w, `{"code":-1,"data":null,"msg":"server panic"}`)}}()// 继续处理下一个中间件或路由处理函数next.ServeHTTP(w, r)})
}// 示例的处理函数
func helloHandler(w http.ResponseWriter, r *http.Request) {panic("Oops! Something went wrong.") // 模拟一个错误w.Write([]byte("Hello, Recovery Middleware!"))
}func main() {// 创建一个多路复用器mux := http.NewServeMux()// 注册中间件mux.Handle("/test", recoveryMiddleware(http.HandlerFunc(helloHandler)))// 创建服务器server := &http.Server{Addr:    ":8080",Handler: mux,}// 启动服务器log.Println("Server is running on http://localhost:8080")log.Fatal(server.ListenAndServe())
}

小结

Web 应用程序在运行时遇到错误并抛出 panic 时,自定义的 recovery 中间件将会捕获panic 并记录对应的错误和堆栈信息,避免应用程序崩溃,并向客户端发送适当的错误响应数据。对于文本的示例,可以根据自己的实际需求进行调整和扩展来实现自定义的 recovery 中间件。

http://www.lryc.cn/news/161957.html

相关文章:

  • Direct3D绘制旋转立方体例程
  • ElementUI浅尝辄止31:Tabs 标签页
  • 将 ChatGPT 用于数据科学项目的指南
  • 06-JVM对象内存回收机制深度剖析
  • [VSCode] 替换掉/去掉空行
  • 时序分解 | MATLAB实现ICEEMDAN+SE改进的自适应经验模态分解+样本熵重构分量
  • python内网环境安装第三方包【内网搭建开发环境】
  • 7.13 在SpringBoot中 正确使用Validation实现参数效验
  • Matlab图像处理之Lee滤波器
  • C++系列-const修饰的常函数
  • fail-safe 机制与 fail-fast 机制
  • LLM 位置编码及外推
  • 第3章_瑞萨MCU零基础入门系列教程之开发环境搭建与体验
  • AI在医疗保健领域:突破界限,救治生命
  • centos7安装kubernets集群
  • 【多线程】线程安全与线程同步
  • 指针权限,new与delete,类与对象,函数模板,类模板的用法
  • Unity——脚本与序列化
  • NJ求职盘点
  • 01卡特兰数
  • 若依前端vue设置子路径
  • Vue中使用pdf.js实现在线预览pdf文件流
  • 态、势、感、知与时空、关系
  • D. Paths on the Tree
  • CocosCreator3.8研究笔记(九)CocosCreator 场景资源的理解
  • 大数据课程L1——网站流量项目的概述整体架构
  • 提升数据库安全小技巧,使用SSH配合开源DBeaver工具连接数据库
  • 信息安全技术概论-李剑-持续更新
  • java项目基于 SSM+JSP 的人事管理系统
  • 【Node.js】—基本知识点总结