Buffalo 路由不支持 per-route 超时设置,超时控制仅能在 http.Server 实例(空闲超时)或 handler 内 context.WithTimeout(业务逻辑超时)中实现,且必须手动构造 http.Server 并传递 context。

Buffalo 路由本身不支持 per-route 超时设置
Buffalo 的 app.GET()、app.POST() 等路由注册方法只是把 handler 绑定到内部路由器(默认是 gorilla/mux),它不提供类似 ctx.WithTimeout() 或 http.Server.ReadTimeout 那样的路由级超时参数。所有“超时”必须在更上层或更底层控制。
真正有效的超时控制点只有两个位置
你得明确自己要防什么类型的超时:
-
HTTP 连接空闲超时(如客户端突然断连、长轮询挂起):必须设在
http.Server实例上,比如ReadTimeout、WriteTimeout、IdleTimeout -
业务逻辑执行超时(如 DB 查询卡住、外部 API 响应慢):必须在 handler 内部用
context.WithTimeout(c.Request().Context(), ...)包裹关键操作,不能依赖路由配置
例如,在 action 里写:
app.Serve()
或 app.Start() 会直接调用 http.ListenAndServe(),此时你完全失去对 http.Server 的控制权,ReadTimeout 等字段根本没机会设置。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
正确做法是手动构造 http.Server:
- 删掉
app.Serve()调用 - 用
&http.Server{Addr: ":3000", Handler: app.Handler, ReadTimeout: 30 * time.Second, WriteTimeout: 60 * time.Second}启动 - 确保所有中间件(包括日志、auth)都显式从
r.Context()提取并传递 context,否则WithTimeout对它们无效
容易被忽略的兼容性陷阱
Go 1.26+ 默认启用了 http.TimeoutHandler 的新行为,但 Buffalo 没做适配。如果你在中间件里手动 wrap handler 用 http.TimeoutHandler,要注意:
- 它只包装
http.Handler,不处理buffalo.Context生命周期,可能造成 panic - 它返回的错误是
http.ErrHandlerTimeout,不是标准 status code,前端收不到 408 - 它无法中断正在写的 response body,只在下一次
WriteHeader()时生效
真要细粒度控制,优先用 context.WithTimeout() + 显式检查 ctx.Err(),而不是依赖外层 wrapper。










