fiber.Default() 不可用于生产环境,因其默认开启的 Recover 中间件会暴露完整 panic 堆栈;应使用 fiber.New() 手动配置 recover.New(recover.Config{EnableStackTrace: false}) 并为子协程单独加 defer-recover。

fiber.Default() 会自动开启 recover,但生产环境不能用它
fiber.Default() 确实内置了 Recover 中间件,但它会在 panic 时直接返回完整堆栈到响应体,暴露内部路径、变量名甚至密钥——上线等于裸奔。你看到的“500 Internal Server Error”页面里藏着 panic: invalid memory address 和调用链,这不该出现在生产环境。
真正可控的 recover 必须手动挂载,且只在 fiber.New() 创建的空实例上配置:
-
fiber.New()初始化后,显式调用app.Use(recover.New()) - 不要依赖
fiber.Default()的默认行为,哪怕只是临时调试 - 如果用了
recover.New(),记得检查它的Config.EnableStackTrace字段,默认是true,必须设为false才安全
recover.New() 的默认行为会泄露 panic 堆栈
recover.New() 不是“开了就安全”,它默认把 panic 信息原样写进 HTTP 响应体,和 fiber.Default() 的问题一模一样。你得主动关掉堆栈输出:
- 显式传入配置:
app.Use(recover.New(recover.Config{EnableStackTrace: false})) - 此时 panic 发生后只会返回
500 Internal Server Error,不带任何细节 - 若需记录日志,用
Config.Handler自定义处理逻辑,比如写入zerolog并采样 - 别在
Handler里调c.Status(500).Send()——recover中间件已接管响应,重复写会 panic
recover 只捕获当前 goroutine,HTTP handler 里必须单独防护
Fiber 的每个请求都在独立 goroutine 中执行,recover 中间件只对当前请求 goroutine 生效。但它无法兜底子协程里的 panic:
立即学习“go语言免费学习笔记(深入)”;
- 你在 handler 里启了个
go doSomething(),里面 panic 了?recover.New()完全没用 - 必须在子协程内自己包一层:
go func() { defer func() { if r := recover(); r != nil { log.Printf("worker panic: %v", r) } }(); doSomething() }() - 别指望“全局 recover 中间件”能覆盖所有协程,这是 Go 的运行时限制,不是 Fiber 的缺陷
- recover 后的状态不可信:map 已被并发写坏、channel 已 close、指针已 nil —— 别在 recover 分支里继续操作它们
ctx.Next() 被跳过?可能是 recover 中间件提前写了响应
如果你发现某个中间件(比如权限校验)之后的 handler 没执行,而 recover 中间件又刚好在它前面,大概率是 recover 在 panic 后已调用 c.Status(500).Send(),导致后续中间件被跳过:
-
recover.New()默认行为是写响应并终止链路,不会调c.Next() - 若你自定义了
Config.Handler,切记不要在其中调c.Send()或c.JSON()—— Fiber 已在 recover 内部完成响应写入 - 调试时可在每个中间件开头加
log.Printf("in %s", "middleware-name"),看执行流在哪断掉 - 真正需要“软着陆 + 继续执行”的场景极少,多数时候 panic 就该终止当前请求
EnableStackTrace 关闭、子协程各自有 defer+recover、日志不落盘敏感字段。


















