最快速定位请求卡点是在handler中用c.SendString()临时返回可识别字符串,如"[DEBUG] before DB call";c.Locals值“消失”主因是fiber.Ctx复用导致被后续请求覆盖,需显式类型断言且避免跨goroutine存储。

直接在 c.JSON() 前加日志或用 c.Locals 注入调试标记,是最快速定位请求卡在哪一步的方式;Fiber 的零内存分配特性意味着上下文复用频繁,不及时清理 c.Locals 或误存指针会导致静默状态污染。
怎么在 handler 里快速打点验证执行流
别依赖全局 logger 或异步日志库——它们可能因协程调度延迟或缓冲未刷出而漏掉关键路径。最稳的做法是在 handler 开头/关键分支处用 c.SendString() 或 c.Status(200).Send() 临时“截停”并返回可识别的字符串,比如 "[DEBUG] before DB call"。
- 确保所有调试输出都走
c对象,避免跨请求污染(Fiber 的fiber.Ctx是复用的) - 若需带变量值,用
fmt.Sprintf拼接后传给c.SendString,不要用log.Printf打印上下文字段 - 上线前必须删掉所有
c.SendString调试语句,否则会覆盖真实响应
为什么 c.Locals 里的值有时“消失”或错乱
c.Locals 是请求生命周期内的键值存储,但它的底层是 map + sync.Pool 复用机制。常见问题不是“没设”,而是“被下个请求覆盖”——尤其在中间件和 handler 之间传递数据时。
- 中间件中设置:
c.Locals("user_id", 123),handler 中必须用c.Locals("user_id").(int)显式断言类型,不能直接赋值给 int 变量 - 禁止把
&c或c.Context()存进 goroutine,fiber.Ctx不是线程安全的 - 如果用了自定义中间件链,检查是否某个中间件提前
return了,导致后续 handler 没执行,c.Locals看似“丢失”
如何排查中间件顺序引发的静默失败
Fiber 的中间件是洋葱模型:注册顺序即执行顺序,且路由级中间件会插入到全局中间件链的对应位置。一个典型陷阱是 auth 中间件放在 logger 后面,结果未授权请求连日志都不记。
- 在每个中间件开头加
c.Locals("trace", append(c.Locals("trace").([]string), "auth")),最后统一打印完整链路 - 用
c.Next()前后各打一次c.Locals("step"),确认是否真正进入下一个中间件 - 特别注意
app.Use("/api", ...)这类前缀匹配中间件——它只对匹配路径生效,容易误以为是全局
调试时 panic 报错看不到 fiber.Ctx 信息怎么办
Fiber 默认 recover 中间件会吞掉 panic 并返回 500,但不输出原始堆栈。要看到真实错误位置,必须手动替换或增强 recover 行为。
- 禁用默认 recover:
fiber.New(fiber.Config{DisableStartupMessage: true, DisableDefaultRecover: true}) - 自己写 recover 中间件,在
recover()后调用debug.PrintStack(),再c.Status(500).SendString("panic") - 注意:生产环境务必关掉
debug.PrintStack(),避免泄露敏感路径
真正难 debug 的从来不是报错,而是 c.Locals 里那个本该有却为空的 "session_id",或者日志里反复出现的同一行 "[DEBUG] after middleware A" 却永远等不到 "after middleware B" —— 那说明中间件链在某处静默中断了,而不是代码写错了。











