ErrorMiddleware在gin中间件放前还是后
2026/7/30 12:37:52 网站建设 项目流程

放最前面(越早注册越好)。

go

r := gin.New() // ✅ 正确:ErrorMiddleware 第一个注册 r.Use(ErrorMiddleware()) // 其他中间件 r.Use(LoggerMiddleware()) r.Use(AuthMiddleware()) r.Use(CORSMiddleware()) // 路由 r.GET("/api/user", getUser)

为什么必须放前面?

Gin 中间件是洋葱模型,注册顺序决定嵌套层次:

plain

ErrorMiddleware (最外层) └── LoggerMiddleware └── AuthMiddleware └── Handler (最内层)

1. recover 必须在最外层

defer recover()只能捕获同一线程(goroutine)内的 panic。如果ErrorMiddleware放在后面:

go

r.Use(AuthMiddleware()) // 如果这里 panic,ErrorMiddleware 捕获不到! r.Use(ErrorMiddleware()) // ❌ 太晚了

只有放在最前面,它的defer才能包裹住后续所有中间件和 Handler。

2. c.Errors 检查不受顺序影响(但放前面更统一)

因为c.Errors是在c.Next()之后检查,无论放哪都能拿到前面累积的错误。但通常规范是:

  • 错误恢复/统一响应 → 最前面

  • 日志记录 → 放 ErrorMiddleware 后面(让它先恢复,再记录)

  • 鉴权/限流 → 更后面

常见正确顺序

go

r.Use(ErrorMiddleware()) // 1. 恢复 + 统一错误响应 r.Use(LoggerMiddleware()) // 2. 记录请求日志(包括错误状态) r.Use(AuthMiddleware()) // 3. 鉴权 r.Use(RateLimit()) // 4. 限流

⚠️ 注意:不要和 gin.Recovery() 一起用

如果你已经用了gin.Default()(内置 Recovery),不要再套自己的 recover,否则内置的先捕获,你的ErrorMiddleware永远 recover 不到:

go

// ❌ 错误:gin.Default 已经内置 Recovery r := gin.Default() r.Use(ErrorMiddleware()) // 这里的 recover 永远抓不到 panic // ✅ 正确:用 gin.New() + 你自己的 ErrorMiddleware r := gin.New() r.Use(ErrorMiddleware())

一句话总结:recover 中间件就像 try-catch,必须包在最外层。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询